Ändern von Daten über eine Sicht

Sie können über eine Sicht die Daten einer zugrunde liegenden Basistabelle ändern, wie Sie das vom Ändern von Daten in einer Tabelle kennen: Durch UPDATE-, INSERT- und DELETE-Anweisungen oder durch das Hilfsprogramm bcp und die BULK INSERT-Anweisung. Allerdings gelten für das Aktualisieren von Sichten die folgenden Einschränkungen, die jedoch nicht für Tabellen gelten:

HinweisHinweis

Einige der folgenden Einschränkungen gelten nicht für partitionierte Sichten, und keine der Einschränkungen gilt für Updates, die über INSTEAD OF-Trigger erfolgt sind. Weitere Informationen finden Sie unter "Andere Optionen für das Ändern von Daten über eine Sicht" weiter unten in diesem Thema.

  • Alle Änderungen, einschließlich Änderungen durch UPDATE-, INSERT- und DELETE-Anweisungen, müssen auf Spalten aus lediglich einer Basistabelle verweisen.

  • Die in der Sicht geänderten Spalten müssen direkt auf die zugrunde liegenden Daten der Tabellenspalten verweisen. Sie können nicht auf andere Weise abgeleitet werden, zum Beispiel durch:

    • Eine Aggregatfunktion (AVG, COUNT, SUM, MIN, MAX, GROUPING, STDEV, STDEVP, VAR und VARP).

    • Eine Berechnung: Die Spalte darf nicht aus einem Ausdruck mithilfe anderer Spalten berechnet werden. Spalten, die mithilfe von Mengenoperatoren (UNION, UNION ALL, CROSSJOIN, EXCEPT und INTERSECT) gebildet wurden, laufen auf eine Berechnung hinaus und sind ebenfalls nicht aktualisierbar.

  • Die geänderten Spalten dürfen nicht von GROUP BY-, HAVING- oder DISTINCT-Klauseln betroffen sein.

  • TOP darf nicht an einer beliebigen Stelle in select_statement der Sicht verwendet werden, wenn WITH CHECK OPTION ebenfalls angegeben ist.

Die vorherigen Einschränkungen gelten für alle Unterabfragen in der FROM-Klausel der Sicht, so wie sie auch für die Sicht selbst gelten. Allgemein gilt: SQL Server muss in der Lage sein, Änderungen aus der Sichtdefinition eindeutig zu einer Basistabelle zurückverfolgen zu können. Beispielsweise ist die folgende Sicht nicht aktualisierbar:

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;

Eine Änderung an der LastName-Spalte von TotalSalesContacts wäre unzulässig, weil die Spalte von einer GROUP BY-Klausel betroffen ist. Falls es nämlich mehrere Instanzen desselben Nachnamens in der Spalte gibt, würde SQL Server nicht wissen, welche davon aktualisiert, eingefügt oder gelöscht werden soll. Desgleichen würde ein Versuch zum Ändern der TotalSales-Spalte in TotalSalesContacts zu einem Fehler führen, weil dies eine Spalte ist, die aus einer Aggregatfunktion abgeleitet wurde. SQL Server kann diese Spalte nicht direkt bis zur Basistabelle SalesOrderHeader zurückverfolgen.

Es gelten folgende zusätzliche Einschränkungen:

  • Alle Anweisungen zur Datenbearbeitung, die auf der Sicht ausgeführt werden, müssten die Einhaltung der Kriterien sicherstellen, die in der die Sicht definierenden SELECT-Anweisung festgelegt wurden, falls die WITH CHECK OPTION-Klausel in der Definition der Sicht verwendet wurde. Wenn die WITH CHECK OPTION-Klausel verwendet wird, ist es nicht möglich, Zeilen so zu ändern, dass sie nicht mehr in der Sicht angezeigt werden. Jede Bearbeitung einer Zeile, die dies zur Folge hätte, wird abgebrochen, und ein Fehler wird angezeigt.

  • INSERT-Anweisungen müssen Werte für Spalten in der zugrunde liegenden Tabelle angeben, die keine NULL-Werte zulassen und über keine DEFAULT-Definitionen verfügen.

  • Die geänderten Daten in den Spalten der zugrunde liegenden Tabelle müssen den Einschränkungen für diese Spalten (NULL-Zulässigkeit, Einschränkungen, DEFAULT-Definitionen usw.) folgen. Wenn z. B. eine Zeile gelöscht wird, müssen alle zugrunde liegenden FOREIGN KEY-Einschränkungen in den zugehörigen Tabellen weiterhin erfüllt werden, damit der Löschvorgang erfolgreich durchgeführt werden kann.

  • Eine verteilte partitionierte Sicht (Remotesicht) kann nicht mithilfe eines keysetgesteuerten Cursors aktualisiert werden. Diese Einschränkung kann aufgehoben werden, indem der Cursor für die zugrunde liegenden Tabellen und nicht für die Sicht deklariert wird.

  • Der Massenimport von Daten in eine partitionierte Sicht wird nicht unterstützt, wennbcp, BULK INSERT oder INSERT ... SELECT * FROM OPENROWSET(BULK...)- Anweisungen verwendet werden. Sie können mit der INSERT-Transact-SQL-Anweisung jedoch mehrere Zeilen in eine partitionierte Sicht einfügen. Weitere Informationen finden Sie unter Massenexport von Daten aus einer Sicht oder Massenimport von Daten in eine Sicht.

  • In einer Sicht können die READTEXT- und WRITETEXT-Anweisungen nicht für Spalten des Typs text, ntext oder image verwendet werden.

Andere Optionen für das Ändern von Daten über eine Sicht

Wenn Sie aufgrund der zuvor in diesem Thema beschriebenen Einschränkungen die Daten nicht direkt über eine Sicht ändern können, sollten Sie die folgenden Optionen berücksichtigen:

  • Verwenden von INSTEAD OF-Triggern mit Logik zur Unterstützung von INSERT-, UPDATE- und DELETE-Anweisungen. Weitere Informationen finden Sie unter Entwerfen von INSTEAD OF-Triggern.

  • Verwenden aktualisierbarer partitionierter Sichten, die mindestens eine Elementtabelle ändern. Weitere Informationen finden Sie unter Erstellen von partitionierten Sichten.

So fügen Sie Daten über eine Sicht hinzu

So ändern Sie Daten über eine Sicht

So löschen Sie Daten über eine Sicht

Siehe auch

Konzepte