То, subquery
что у вас есть в вашем коде, называется производной таблицей . Это не базовая таблица, а таблица, которая «живет» во время выполнения запроса. Подобно представлениям (которые также называются просматриваемыми таблицами ) - и в последних версиях CTE, что является еще одним, четвертым способом «определения» таблицы внутри запроса - они во многом похожи на таблицу. Вы можете select
из них, вы можете использовать их в from
или join
к другим таблицам (базы или нет!).
В некоторых СУБД (не все СУБД реализовали это одинаково) эти таблицы / представления являются обновляемыми . И «обновляемый» означает, что мы также можем update
, insert
в или delete
из них.
Хотя есть ограничения, и это ожидается. Представьте, если это subquery
было объединение 2 (или 17 таблиц). Что бы delete
тогда значило? (из каких таблиц следует удалять строки?) Обновляемые представления - это очень сложный вопрос . Недавно вышла книга (2012), полностью посвященная этой теме, написанная Крисом Дейтом, известным специалистом по теории отношений: « Обновление представлений и теория отношений» .
Когда производная таблица (или представление) представляет собой очень простой запрос, например, он имеет только одну базовую таблицу (возможно, ограниченную символом a WHERE
) и no GROUP BY
, тогда каждая строка производной таблицы соответствует одной строке в базовой базовой таблице, поэтому легко * обновить, вставить или удалить из этого.
Когда код внутри подзапроса более сложен, это зависит от того, можно ли отследить / разрешить строки производной таблицы / представления в строки из одной из базовых базовых таблиц.
Для SQL Server, вы можете прочитать в пункте обновляемых представлений в MSDN: CREATE VIEW
.
Обновляемые виды
Вы можете изменить данные базовой базовой таблицы через представление, если выполняются следующие условия:
Любые модификации, в том числе UPDATE
, INSERT
и DELETE
утверждения, должны ссылаться на столбцы только из одной базовой таблицы.
Столбцы, изменяемые в представлении, должны напрямую ссылаться на базовые данные в столбцах таблицы. Столбцы не могут быть получены любым другим способом, например, с помощью следующего:
Агрегатная функция: AVG
, COUNT
, SUM
, MIN
, MAX
, GROUPING
, STDEV
, STDEVP
, VAR
, и VARP
.
Вычисление. Столбец не может быть вычислен из выражения, которое использует другие столбцы. Столбцы, которые сформированы с использованием набора операторов UNION
, UNION ALL
, CROSSJOIN
, EXCEPT
, и INTERSECT
количества к вычислению и также не обновляемые.
На изменяемые столбцы не распространяются ни слова GROUP BY
, HAVING
ни DISTINCT
предложения.
TOP
не используется нигде в select_statement представления вместе с WITH CHECK OPTION
предложением.
Предыдущие ограничения применяются к любым подзапросам в FROM
предложении представления так же, как они применяются к самому представлению. Как правило, компонент Database Engine должен иметь возможность однозначно отслеживать изменения из определения представления в одной базовой таблице.
На самом деле delete
это проще, менее сложно, чем update
. SQL Server нужны только первичные ключи или какой-либо другой способ определить, какие строки базовой таблицы следует удалить. Поскольку update
есть дополнительное (довольно очевидное) ограничение, что мы не можем обновить вычисляемый столбец. Вы можете попытаться изменить свой запрос, чтобы сделать обновление. Обновление CreatedDateTime
, вероятно, будет работать нормально, но попытка обновить вычисляемый RowNumber
столбец вызовет ошибку. И insert
это еще более сложно, так как мы должны были бы предоставить значения для всех столбцов базовой таблицы, которые не имеют DEFAULT
ограничений.