Изменение данных через представление
Данные, содержащиеся в базовой таблице, могут быть изменены в представлении таким же образом, как и при изменении данных в самой таблице, то есть инструкциями UPDATE, INSERT и DELETE или с помощью программы bcp и инструкции BULK INSERT. Однако на изменение данных через представления налагаются следующие ограничения.
Примечание |
---|
Некоторые из этих ограничений не применяются к секционированным представлениям, и ни одно из них не применяется к изменениям, выполняемым триггерами типа INSTEAD OF. Дополнительные сведения см. в статье «Другие методы изменения данных через представление» ниже в этом разделе. |
Любые изменения, в том числе инструкции 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, равно как и к самому представлению. Обычно в SQL Server должна быть предусмотрена возможность однозначно отслеживать изменяемые значения в базовой таблице из определения представления. Например, следующее представление является неизменяемым:
USE AdventureWorks2008R2;
GO
CREATE VIEW Sales.TotalSalesContacts
AS
SELECT p.LastName,
SUM(o.TotalDue) AS TotalSales
FROM Sales.SalesOrderHeader AS o, Person.Person AS p
WHERE p.BusinessEntityID = o.CustomerID
GROUP BY LastName;
Изменение столбца LastName в таблице TotalSalesContacts будет неприемлемо, так как на этот столбец указывает предложение GROUP BY. Если существует более одного экземпляра одной и той же фамилии, SQL Server не будет знать, которую из них следует обновить, вставить или удалить. Аналогичным образом, попытка изменить столбец TotalSales в таблице TotalSalesContacts возвратит ошибку, так как столбец является производным агрегатной функции. SQL Server не может связать напрямую данный столбец со столбцом базовой таблицы SalesOrderHeader.
Применяются следующие дополнительные рекомендации.
Все инструкции изменения данных, выполняемые для представления, должны придерживаться перечня критериев, указанных в инструкции SELECT, определяющей представление, если при этом использовано предложение WITH CHECK OPTION. При указании этого предложения строки не могут быть изменены способом, который приводит к их исчезновению из представления. Любое изменение, которое может к этому привести, отменяется, и выдается ошибка.
Инструкция INSERT должна указывать значения для всех столбцов базовой таблицы, которые не допускают значений NULL и не определены с ключевым словом DEFAULT.
Данные, изменившиеся в столбцах базовой таблицы, должны соответствовать требованиям, налагаемым на эти столбцы (возможность содержать значение NULL, ограничения, определения DEFAULT и т. д.). Например, для успешного удаления строки это удаление должно удовлетворять условиям всех ограничений FOREIGN KEY в связанных таблицах.
Распределенное секционированное представление (удаленное представление) не может быть изменено при использовании курсора, управляемого набором ключей. Это ограничение может быть разрешено объявлением курсора для базовой таблицы, а не для представления.
Инструкции bcp, BULK INSERT и INSERT ... SELECT * FROM OPENROWSET(BULK...) . Однако можно вставить в секционированное представление несколько строк с помощью инструкции INSERT. Дополнительные сведения см. в разделе Массовый экспорт данных из представления или массовый импорт данных в него.
Инструкции READTEXT и WRITETEXT не могут применяться к столбцам представления типа text, ntext или image.
Другие методы изменения данных через представление
Если описанные выше ограничения не позволяют изменить данные через представление напрямую, рассмотрите следующие варианты.
Реализовать триггеры типа INSTEAD OF с логикой поддержки инструкций INSERT, UPDATE и DELETE. Дополнительные сведения см. в разделе Конструирование триггеров INSTEAD OF.
Использовать изменяемые секционированные представления, которые изменяют одну или несколько таблиц. Дополнительные сведения см. в разделе Создание секционированных представлений.
Добавление данных через представление
Изменение данных через представление
Удаление данных через представление