Freigeben über


UPDATE (Transact-SQL)

Ändert vorhandene Daten in einer Tabelle oder Sicht in SQL Server 2014. Beispiele finden Sie unter Beispiele.

Gilt für: SQL Server (SQL Server 2008 bis aktuelle Version), Windows Azure SQL-Datenbank (Ursprüngliche Version bis aktuelle Version).

Themenlink (Symbol) Transact-SQL-Syntaxkonventionen

Syntax

[ WITH <common_table_expression> [...n] ]
UPDATE 
    [ TOP ( expression ) [ PERCENT ] ] 
    { { table_alias | <object> | rowset_function_limited 
         [ WITH ( <Table_Hint_Limited> [ ...n ] ) ]
      }
      | @table_variable    
    }
    SET
        { column_name = { expression | DEFAULT | NULL }
          | { udt_column_name.{ { property_name = expression
                                | field_name = expression }
                                | method_name ( argument [ ,...n ] )
                              }
          }
          | column_name { .WRITE ( expression , @Offset , @Length ) }
          | @variable = expression
          | @variable = column = expression
          | column_name { += | -= | *= | /= | %= | &= | ^= | |= } expression
          | @variable { += | -= | *= | /= | %= | &= | ^= | |= } expression
          | @variable = column { += | -= | *= | /= | %= | &= | ^= | |= } expression
        } [ ,...n ] 

    [ <OUTPUT Clause> ]
    [ FROM{ <table_source> } [ ,...n ] ] 
    [ WHERE { <search_condition> 
            | { [ CURRENT OF 
                  { { [ GLOBAL ] cursor_name } 
                      | cursor_variable_name 
                  } 
                ]
              }
            } 
    ] 
    [ OPTION ( <query_hint> [ ,...n ] ) ]
[ ; ]

<object> ::=
{ 
    [ server_name . database_name . schema_name . 
    | database_name .[ schema_name ] . 
    | schema_name .
    ]
    table_or_view_name}

Argumente

  • WITH <common_table_expression>
    Gibt den temporären Resultset- oder Sichtnamen an, der auch als allgemeiner Tabellenausdruck (CTE, Common Table Expression) bezeichnet wird und innerhalb der UPDATE-Anweisung definiert ist. Das CTE-Resultset wird aus einer einfachen Abfrage abgeleitet. Die UPDATE-Anweisung verweist auf dieses Resultset.

    Allgemeine Tabellenausdrücke können auch mit den Anweisungen SELECT, INSERT, DELETE und CREATE VIEW verwendet werden. Weitere Informationen finden Sie unter WITH common_table_expression (Transact-SQL).

  • TOP ( expression**)** [ PERCENT ]
    Gibt die Anzahl oder den Prozentsatz der Zeilen an, die aktualisiert werden. expression kann eine Anzahl oder ein Prozentsatz der Zeilen sein.

    Die Zeilen, auf die im TOP-Ausdruck für die Anweisung INSERT, UPDATE oder DELETE verwiesen wird, sind nicht auf bestimmte Weise angeordnet.

    In INSERT-, UPDATE- und DELETE-Anweisungen sind Klammern, die expression in TOP begrenzen, erforderlich. Weitere Informationen finden Sie unter TOP (Transact-SQL).

  • table_alias
    Der in der FROM-Klausel angegebene Alias, der die Tabelle oder Sicht darstellt, aus der die Zeilen aktualisiert werden sollen.

  • server_name
    Der Name des Servers (mithilfe eines Verbindungsservernamens oder der OPENDATASOURCE-Funktion als Servername), auf dem sich die Tabelle oder die Sicht befindet. Wenn server_name angegeben ist, sind database_name und schema_name erforderlich.

  • database_name
    Der Name der Datenbank.

  • schema_name
    Der Name des Schemas, zu dem die Tabelle oder Sicht gehört.

  • table_or view_name
    Der Name der Tabelle oder Sicht, aus der die Zeilen aktualisiert werden sollen. Die Sicht, auf die table_or_view_name verweist, muss aktualisierbar sein und auf genau eine Basistabelle in der FROM-Klausel der Sicht verweisen. Weitere Informationen zu aktualisierbaren Sichten finden Sie unter CREATE VIEW (Transact-SQL).

  • rowset_function_limited
    Die OPENQUERY-Funktion oder OPENROWSET-Funktion, die der Funktionalität des Anbieters unterliegt.

  • WITH ( <Table_Hint_Limited> )
    Gibt mindestens einen Tabellenhinweis an, der für eine Zieltabelle zulässig ist. Das WITH-Schlüsselwort und die Klammern sind erforderlich. NOLOCK und READUNCOMMITTED sind nicht zulässig. Weitere Informationen zu Tabellenhinweisen finden Sie unter Tabellenhinweise (Transact-SQL).

  • @table\_variable
    Gibt eine table-Variable als Tabellenquelle an.

  • SET
    Gibt die Liste der zu aktualisierenden Spalten- oder Variablennamen an.

  • column_name
    Eine Spalte mit Daten, die geändert werden sollten. column_name muss in table_or view_name vorhanden sein. Identitätsspalten können nicht aktualisiert werden.

  • expression
    Eine Variable, ein Literalwert, ein Ausdruck oder eine SELECT-Anweisung als Unterabfrage in Klammern, die bzw. der einen einzelnen Wert zurückgibt. Der von expression zurückgegebene Wert ersetzt den vorhandenen Wert in column_name oder @variable.

    Hinweis

    In Verweisen auf die Unicodezeichen-Datentypen nchar, nvarchar und ntext muss "expression" der Großbuchstabe "N" vorangestellt werden.Wenn "N" nicht angegeben wird, konvertiert SQL Server die Zeichenfolge in die Codepage, die der Standardsortierung der Datenbank oder Spalte entspricht.Alle Zeichen, die in der betreffenden Codepage nicht gefunden werden, gehen verloren.

  • DEFAULT
    Gibt an, dass der vorhandene Wert in der Spalte durch den für die Spalte definierten Standardwert ersetzt werden soll. Damit kann auch die Spalte auf NULL geändert werden, wenn diese keinen Standard aufweist und NULL-Werte zulässt.

  • { += | -= | *= | /= | %= | &= | ^= | |= }
    Verbundzuweisungsoperator:

    += Addition und Zuweisung

    -= Subtraktion und Zuweisung

    *= Multiplikation und Zuweisung

    /= Division und Zuweisung

    %= Modulo und Zuweisung

    &= Bitweises AND und Zuweisung

    ^= Bitweises XOR und Zuweisung

    |= Bitweises OR und Zuweisung

  • udt_column_name
    Eine benutzerdefinierte Spalte.

  • property_name | field_name
    Member einer öffentlichen Eigenschaft oder öffentlicher Daten eines benutzerdefinierten Typs.

  • method_name ( argument [ ,... n] )
    Eine nicht statische, öffentliche Mutatormethode von udt_column_name, die ein oder mehrere Argumente umfassen kann.

  • .WRITE (expression,@Offset,@Length**)**
    Gibt an, dass ein Teil des Werts von column_name geändert werden soll. expression ersetzt @Length Einheiten, beginnend mit @Offset von column_name. Für diese Klausel können nur Spalten von varchar(max), nvarchar(max) oder varbinary(max) angegeben werden. column_name kann werden NULL sein noch mit einem Tabellennamen oder -alias qualifiziert werden.

    expression ist der Wert, der in column_name kopiert wird. expression muss in den column_name-Typ ausgewertet werden oder implizit umgewandelt werden können. Wenn expression auf NULL festgelegt wird, wird @Length ignoriert, und der Wert in column_name wird am angegebenen @Offset abgeschnitten.

    @Offset ist der Ausgangspunkt im Wert von column_name, an dem expression geschrieben wird. @Offset ist eine nullbasierte Ordnungsposition, weist den Datentyp bigint auf, und kann keine negative Zahl sein. Wenn @Offset NULL ist, hängt der Updatevorgang expression am Ende des vorhandenen column_name-Werts an, und @Length wird ignoriert. Falls @Offset größer als die Länge von column_name ist, gibt Database Engine (Datenbankmodul) einen Fehler zurück. Wenn @Offset zuzüglich @Length das Ende des zugrunde liegenden Werts in der Spalte übersteigt, findet der Löschvorgang bis zum letzten Zeichen des Werts statt. Wenn @Offset zuzüglich LEN(expression) größer als die zugrunde liegende deklarierte Größe ist, wird ein Fehler ausgelöst.

    @Length ist die Länge des Abschnitts in der Spalte ab @Offset, der von expression ersetzt wird. @Length ist bigint und kann keine negative Zahl sein. Wenn @Length NULL ist, entfernt der Updatevorgang alle Daten aus @Offset bis zum Ende des column_name-Werts.

    Weitere Informationen finden Sie in den Hinweisen.

  • @ variable
    Eine deklarierte Variable, die auf den von expression zurückgegebenen Wert festgelegt wird.

    SET **@**variable = column = expression legt die Variable auf denselben Wert wie die Spalte fest. Diese Anweisung unterscheidet sich von SET **@**variable = column, column = expression, wodurch die Variable auf den Wert der Spalte vor dem Update festgelegt wird.

  • <OUTPUT_Clause>
    Gibt aktualisierte Daten oder Ausdrücke zurück, die darauf als Teil des UPDATE-Vorgangs basieren. Die OUTPUT-Klausel wird nicht in DML-Anweisungen unterstützt, die an Remotetabellen oder -sichten gerichtet sind. Weitere Informationen finden Sie unter OUTPUT-Klausel (Transact-SQL).

  • FROM <table_source>
    Gibt an, dass eine Tabelle, Sicht oder abgeleitete Tabelle als Quelle die Kriterien für den Updatevorgang bereitstellen soll. Weitere Informationen finden Sie unter FROM (Transact-SQL).

    Wenn das Objekt, das aktualisiert wird, mit dem Objekt in der FROM-Klausel identisch ist und nur ein Verweis auf das Objekt in der FROM-Klausel vorhanden ist, kann ein Objektalias angegeben werden. Wenn das Objekt, das aktualisiert wird, mehrmals in der FROM-Klausel vorhanden ist, darf genau ein Verweis auf das Objekt keinen Tabellenalias angeben. Alle anderen Verweise auf das Objekt in der FROM-Klausel müssen einen Objektalias aufweisen.

    Eine Sicht mit einem INSTEAD OF UPDATE-Trigger kann nicht Ziel für eine UPDATE-Anweisung mit einer FROM-Klausel sein.

    Hinweis

    Jeder Aufruf von OPENDATASOURCE, OPENQUERY oder OPENROWSET in der FROM-Klausel wird einzeln und unabhängig von anderen Aufrufen dieser Funktionen ausgewertet, die als Ziel des Updates verwendet werden, auch wenn für die beiden Aufrufe identische Argumente angegeben werden.Insbesondere haben Filter- oder Joinbedingungen, die auf das Ergebnis eines dieser Aufrufe angewendet werden, keine Auswirkungen auf die Ergebnisse des jeweils anderen.

  • WHERE
    Gibt die Bedingungen an, mit denen die zu aktualisierenden Zeilen eingegrenzt werden. Es gibt zwei Arten von Updates, die vom verwendeten WHERE-Klauseltyp abhängen:

    • Gesuchte Updates legen eine Suchbedingung fest, der die zu löschenden Zeilen entsprechen müssen.

    • Positionierte Updates verwenden die CURRENT OF-Klausel, um einen Cursor anzugeben. Der Updatevorgang wird an der aktuellen Position des Cursors ausgeführt.

  • <search_condition>
    Bezeichnet die Bedingung, die erfüllt sein muss, damit die Zeilen aktualisiert werden. Die Suchbedingung kann auch die Bedingung sein, auf der ein Join basiert. Es gibt keinen Höchstwert hinsichtlich der Anzahl von Prädikaten in einer Suchbedingung. Weitere Informationen zu Prädikaten und Suchbedingungen finden Sie unter Suchbedingung (Transact-SQL).

  • CURRENT OF
    Gibt an, dass das Update an der aktuellen Position des angegebenen Cursors ausgeführt wird.

    Ein positioniertes Update, das eine WHERE CURRENT OF-Klausel verwendet, aktualisiert die Einzelzeile an der aktuellen Cursorposition. Dies kann genauer sein als ein gesuchtes Update, das eine WHERE <search_condition>-Klausel zur Kennzeichnung der zu aktualisierenden Zeilen verwendet. Mit einem gesuchten Update werden mehrere Zeilen geändert, wenn eine einzelne Zeile durch die Suchbedingung nicht eindeutig identifiziert wird.

  • GLOBAL
    Gibt an, dass cursor_name auf einen globalen Cursor verweist.

  • cursor_name
    Der Name des geöffneten Cursors, von dem der Abruf erfolgen soll. Wenn sowohl ein globaler als auch ein lokaler Cursor namens cursor_name vorhanden sind, bezieht sich dieses Argument auf den globalen Cursor, wenn GLOBAL angegeben ist. Andernfalls bezieht es sich auf den lokalen Cursor. Der Cursor muss Updates zulassen.

  • cursor_variable_name
    Der Name einer Cursorvariablen. cursor_variable_name muss auf einen Cursor verweisen, der Updates zulässt.

  • OPTION ( <query_hint> [ ,... n ] )
    Gibt an, dass mithilfe von Optimierungshinweisen angepasst wird, wie die Anweisung von Database Engine (Datenbankmodul) verarbeitet wird. Weitere Informationen finden Sie unter Abfragehinweise (Transact-SQL).

Bewährte Methoden

Verwenden Sie die @@ROWCOUNT-Funktion, um die Anzahl der eingefügten Zeilen an die Clientanwendung zurückzugeben. Weitere Informationen finden Sie unter @@ROWCOUNT (Transact-SQL).

Variablennamen können in UPDATE-Anweisungen verwendet werden, um die betroffenen alten und neuen Werte anzuzeigen. Diese Vorgehensweise sollte aber nur angewendet werden, wenn die UPDATE-Anweisung einen einzelnen Datensatz betrifft. Betrifft die UPDATE-Anweisung mehrere Datensätze, verwenden Sie die OUTPUT-Klausel, um die alten und neuen Werte für die einzelnen Datensätze zurückzugeben.

Gehen Sie beim Angeben der FROM-Klausel zum Bereitstellen der Kriterien für den Updatevorgang vorsichtig vor. Das Ergebnis einer UPDATE-Anweisung ist nicht definiert, wenn sie nicht deterministisch ist. Dies ist der Fall, wenn die UPDATE-Anweisung eine FROM-Klausel enthält, in der nicht für jedes Vorkommen einer zu aktualisierenden Spalte genau ein Wert verfügbar ist. Beispielsweise erfüllen im folgenden Skript der UPDATE-Anweisung beide Zeilen der Table1-Tabelle die Bedingungen der FROM-Klausel in der UPDATE-Anweisung. Es ist jedoch nicht definiert, welche Zeile von Table1 zum Aktualisieren der Zeile in Table2. verwendet wird.

USE AdventureWorks2012;
GO
IF OBJECT_ID ('dbo.Table1', 'U') IS NOT NULL
    DROP TABLE dbo.Table1;
GO
IF OBJECT_ID ('dbo.Table2', 'U') IS NOT NULL
    DROP TABLE dbo.Table2;
GO
CREATE TABLE dbo.Table1 
    (ColA int NOT NULL, ColB decimal(10,3) NOT NULL);
GO
CREATE TABLE dbo.Table2 
    (ColA int PRIMARY KEY NOT NULL, ColB decimal(10,3) NOT NULL);
GO
INSERT INTO dbo.Table1 VALUES(1, 10.0), (1, 20.0);
INSERT INTO dbo.Table2 VALUES(1, 0.0);
GO
UPDATE dbo.Table2 
SET dbo.Table2.ColB = dbo.Table2.ColB + dbo.Table1.ColB
FROM dbo.Table2 
    INNER JOIN dbo.Table1 
    ON (dbo.Table2.ColA = dbo.Table1.ColA);
GO
SELECT ColA, ColB 
FROM dbo.Table2;

Dasselbe Problem kann auftreten, wenn die Klauseln FROM und WHERE CURRENT OF kombiniert werden. Im folgenden Beispiel erfüllen beide Zeilen der Table2-Tabelle die Bedingungen der FROM-Klausel in der UPDATE-Anweisung. Es ist jedoch nicht definiert, welche Zeile aus Table2 zum Aktualisieren der Zeile in Table1 verwendet wird.

USE AdventureWorks2012;
GO
IF OBJECT_ID ('dbo.Table1', 'U') IS NOT NULL
    DROP TABLE dbo.Table1;
GO
IF OBJECT_ID ('dbo.Table2', 'U') IS NOT NULL
    DROP TABLE dbo.Table2;
GO
CREATE TABLE dbo.Table1
    (c1 int PRIMARY KEY NOT NULL, c2 int NOT NULL);
GO
CREATE TABLE dbo.Table2
    (d1 int PRIMARY KEY NOT NULL, d2 int NOT NULL);
GO
INSERT INTO dbo.Table1 VALUES (1, 10);
INSERT INTO dbo.Table2 VALUES (1, 20), (2, 30);
GO
DECLARE abc CURSOR LOCAL FOR
    SELECT c1, c2 
    FROM dbo.Table1;
OPEN abc;
FETCH abc;
UPDATE dbo.Table1 
SET c2 = c2 + d2 
FROM dbo.Table2 
WHERE CURRENT OF abc;
GO
SELECT c1, c2 FROM dbo.Table1;
GO

Kompatibilitätsunterstützung

Die Unterstützung für die Verwendung der READUNCOMMITTED- und NOLOCK-Hinweise in der FROM-Klausel, die sich auf die Zieltabelle einer UPDATE- oder DELETE-Anweisung beziehen, wird in einer zukünftigen Version von SQL Server entfernt. Vermeiden Sie die Verwendung dieser Hinweise in diesem Kontext beim Entwickeln neuer Anwendungen, und planen Sie die Änderung von Anwendungen, in denen sie derzeit verwendet werden.

Datentypen

Alle char-Spalten und nchar-Spalten werden rechts auf die definierte Länge aufgefüllt.

Wenn ANSI_PADDING auf OFF festgelegt ist, werden alle nachfolgenden Leerzeichen aus den in varchar-Spalten und nvarchar-Spalten eingefügten Daten entfernt. Dies gilt nicht für Zeichenfolgen, die nur aus Leerzeichen bestehen. Diese Zeichenfolgen werden auf eine leere Zeichenfolge abgeschnitten. Wenn ANSI_PADDING auf ON festgelegt ist, werden nachfolgende Leerzeichen eingefügt. Der Microsoft SQL Server-ODBC-Treiber und der OLE DB-Provider für SQL Server stellen beim Herstellen einer Verbindung SET ANSI_PADDING automatisch auf ON ein. Diese Einstellung kann in ODBC-Datenquellen oder durch Festlegen von Verbindungsattributen oder Verbindungseigenschaften konfiguriert werden. Weitere Informationen finden Sie unter SET ANSI_PADDING (Transact-SQL).

Aktualisieren der Spalten "text", "ntext" und "image"

Durch das Ändern einer Spalte des Datentyps text, ntext oder image mit UPDATE wird die Spalte initialisiert, ein gültiger Textzeiger zugewiesen und mindestens eine Datenseite zugeordnet, es sei denn, die Spalte wird mit NULL aktualisiert.

Wenn Sie große Datenblöcke des Datentyps text, ntext oder image ersetzen oder ändern, verwenden Sie statt der UPDATE-Anweisung die WRITETEXT-Anweisung oder die UPDATETEXT-Anweisung.

Wenn die UPDATE-Anweisung beim Aktualisieren des Clusteringschlüssels und mindestens einer Spalte text, ntext oder image nicht mehr als eine Zeile ändern konnte, wird das Teilupdate dieser Spalten als vollständige Ersetzung dieser Werte ausgeführt.

Wichtig

Die Datentypen ntext, text und image werden in einer zukünftigen Version von Microsoft SQL Server entfernt.Vermeiden Sie die Verwendung dieser Datentypen bei neuen Entwicklungen, und planen Sie die Änderung von Anwendungen, in denen sie aktuell verwendet werden.Verwenden Sie stattdessen nvarchar(max), varchar(max) und varbinary(max).

Aktualisieren von Datentypen mit umfangreichen Werten

Verwenden Sie die .WRITE (expression, @Offset**,** @Length)-Klausel zum Ausführen eines teilweisen oder vollständigen Updates der Datentypen varchar(max), nvarchar(max) und varbinary(max). Bei einem teilweisen Update einer varchar(max)-Spalte werden z. B. nur die ersten 200 Zeichen der Spalte gelöscht oder geändert, während bei einem vollständigen Update alle Daten in der Spalte gelöscht oder geändert werden. **.**Updates mit WRITE, bei denen neue Daten eingefügt oder angefügt werden, werden minimal protokolliert, wenn das Wiederherstellungsmodell für die Datenbank auf massenprotokolliert oder einfach festgelegt ist. Die minimale Protokollierung wird nicht verwendet, wenn vorhandene Werte aktualisiert werden. Weitere Informationen finden Sie unter Das Transaktionsprotokoll [SQL Server].

Database Engine (Datenbankmodul) konvertiert ein teilweises Update in ein vollständiges Update, wenn die UPDATE-Anweisung eine dieser Aktionen bewirkt:

  • Ändert eine Schlüsselspalte der partitionierten Sicht oder Tabelle.

  • Ändert mehr als eine Zeile und aktualisiert außerdem den Schlüssel eines nicht eindeutigen gruppierten Index in einen nicht konstanten Wert.

Sie können die **.**WRITE-Klausel nicht zum Aktualisieren einer NULL-Spalte oder zum Festlegen des Werts von column_name auf NULL verwenden.

@Offset und @Length werden in Byte für varbinary- und varchar-Datentypen und in Zeichen für den nvarchar-Datentyp angegeben. Die geeigneten Offsets werden für Doppelbyte-Zeichensatzsortierungen (DBCS, Double-Byte Character Set) berechnet.

Es wird empfohlen, Daten in Blockgrößen einzufügen bzw. zu aktualisieren, die ein Vielfaches von 8.040 Byte sind, um eine optimale Leistung zu erzielen.

Wenn in einer OUTPUT-Klausel auf die von der **.**WRITE-Klausel geänderte Spalte verwiesen wird, wird der vollständige Wert der Spalte (entweder das Anfangsimage in **deleted.**column_name oder das Endimage in **inserted.**column_name)an die angegebene Spalte in der Tabellenvariablen zurückgegeben. Weitere Informationen finden Sie unten im Beispiel G.

Verwenden Sie STUFF (Transact-SQL), um dieselbe Funktionalität von **.**WRITE mit anderen Zeichen- oder Binärdatentypen zu erzielen.

Aktualisieren von Spalten mit benutzerdefiniertem Datentyp

Sie können Werte in benutzerdefinierten Spalten auf eine der folgenden Arten aktualisieren:

  • Bereitstellen eines Werts in einem SQL Server-Systemdatentyp, vorausgesetzt, der benutzerdefinierte Typ unterstützt die implizite oder explizite Konvertierung aus diesem Typ. Im folgenden Beispiel wird gezeigt, wie Sie einen Wert in einer Spalte des benutzerdefinierten Typs Point durch explizites Konvertieren aus einer Zeichenfolge aktualisieren.

    UPDATE Cities
    SET Location = CONVERT(Point, '12.3:46.2')
    WHERE Name = 'Anchorage';
    
  • Aufrufen einer als Mutator markierten Methode des benutzerdefinierten Typs, um das Update auszuführen. Im folgenden Beispiel wird eine Mutatormethode des Typs Point namens SetXY aufgerufen. Dadurch wird der Status der Instanz des Typs aktualisiert.

    UPDATE Cities
    SET Location.SetXY(23.5, 23.5)
    WHERE Name = 'Anchorage';
    

    Hinweis

    Von SQL Server wird ein Fehler zurückgegeben, wenn eine mutator-Methode für einen NULL-Wert von Transact-SQL aufgerufen wird oder wenn ein neuer von einer mutator-Methode generierter Wert NULL ist.

  • Ändern des Werts eines Members einer öffentlichen Eigenschaft oder öffentlicher Daten des benutzerdefinierten Typs. Der Ausdruck, der den Wert bereitstellt, muss implizit in den Typ der Eigenschaft konvertierbar sein. Im folgenden Beispiel wird der Wert der X-Eigenschaft des benutzerdefinierten Typs Point geändert.

    UPDATE Cities
    SET Location.X = 23.5
    WHERE Name = 'Anchorage';
    

    Wenn Sie verschiedene Eigenschaften einer Spalte des gleichen benutzerdefinierten Typs ändern möchten, geben Sie mehrere UPDATE-Anweisungen aus, oder rufen Sie eine Mutatormethode des Typs auf.

Aktualisieren von FILESTREAM-Daten

Sie können ein FILESTREAM-Feld mithilfe der UPDATE-Anweisung auf einen NULL-Wert, einen leeren Wert oder eine relativ kleine Menge von Inlinedaten aktualisieren. Große Datenmengen lassen sich jedoch mithilfe von Win32-Schnittstellen effizienter in eine Datei streamen. Wenn Sie ein FILESTREAM-Feld aktualisieren, ändern Sie die zugrunde liegenden BLOB-Daten im Dateisystem. Wenn ein FILESTREAM-Feld auf NULL festgelegt wird, werden die dem Feld zugeordneten BLOB-Daten gelöscht. Dabei kann .WRITE() nicht zum teilweisen Update der Daten eingesetzt werden. Weitere Informationen finden Sie unter FILESTREAM (SQL Server).

Fehlerbehandlung

Wenn das Update einer Zeile eine Einschränkung oder Regel oder die NULL-Einstellung für die Spalte verletzt bzw. der neue Wert einen inkompatiblen Datentyp hat, wird die Anweisung abgebrochen. Außerdem wird ein Fehler zurückgegeben, und es werden keine Datensätze aktualisiert.

Wenn in einer UPDATE-Anweisung ein arithmetischer Fehler (Überlauf, Division durch Null oder Definitionsbereichsfehler/Domänenfehler) bei der Auswertung eines Ausdrucks auftritt, wird das Update nicht ausgeführt. Der Rest des Batches wird nicht ausgeführt, und eine Fehlermeldung wird zurückgegeben.

Wenn das Update mindestens einer Spalte eines gruppierten Index dazu führt, dass die Größe des gruppierten Index und der Zeile den Wert von 8.060 Byte überschreitet, tritt beim Update ein Fehler auf, und es wird eine Fehlermeldung zurückgegeben.

Interoperabilität

UPDATE-Anweisungen sind im Textkörper von benutzerdefinierten Funktionen nur zulässig, wenn es sich bei der Tabelle, die geändert wird, um eine Tabellenvariable handelt.

Wenn ein INSTEAD-OF-Trigger für UPDATE-Aktionen für eine Tabelle definiert ist, wird der Trigger statt der UPDATE-Anweisung ausgeführt. Frühere Versionen von SQL Server unterstützen nur AFTER-Trigger für UPDATE-Anweisungen und andere Anweisungen zur Datenänderung. Die FROM-Klausel kann nicht in einer UPDATE-Anweisung angegeben werden, die (direkt oder indirekt) auf eine Sicht verweist, für die ein INSTEAD OF-Trigger definiert wurde. Weitere Informationen zu INSTEAD OF-Triggern finden Sie unter CREATE TRIGGER (Transact-SQL).

Einschränkungen

Die FROM-Klausel kann nicht in einer UPDATE-Anweisung angegeben werden, die (direkt oder indirekt) auf eine Sicht verweist, für die ein INSTEAD OF-Trigger definiert wurde. Weitere Informationen zu INSTEAD OF-Triggern finden Sie unter CREATE TRIGGER (Transact-SQL).

Wenn ein allgemeiner Tabellenausdruck das Ziel einer UPDATE-Anweisung ist, müssen alle Verweise auf den allgemeinen Tabellenausdruck in der Anweisung übereinstimmen. Wenn dem allgemeinen Tabellenausdruck z. B. ein Alias in der FROM-Klausel zugewiesen wird, muss der Alias für alle weiteren Verweise auf den allgemeinen Tabellenausdruck verwendet werden. Eindeutige Verweise auf allgemeine Tabellenausdrücke sind erforderlich, da ein allgemeiner Tabellenausdruck keine Objekt-ID hat, mit der SQL Server die implizite Beziehung zwischen einem Objekt und seinem Alias erkennt. Ohne diese Beziehung erzeugt der Abfrageplan möglicherweise ein unerwartetes Joinverhalten und unbeabsichtigte Abfrageergebnisse. In den folgenden Beispielen werden richtige und falsche Methoden zum Angeben eines allgemeinen Tabellenausdrucks veranschaulicht, wenn der allgemeine Tabellenausdruck das Zielobjekt des Updatevorgangs ist.

USE tempdb;
GO
-- UPDATE statement with CTE references that are correctly matched.
DECLARE @x TABLE (ID int, Value int);
DECLARE @y TABLE (ID int, Value int);
INSERT @x VALUES (1, 10), (2, 20);
INSERT @y VALUES (1, 100),(2, 200);

WITH cte AS (SELECT * FROM @x)
UPDATE x -- cte is referenced by the alias.
SET Value = y.Value
FROM cte AS x  -- cte is assigned an alias.
INNER JOIN @y AS y ON y.ID = x.ID;
SELECT * FROM @x;
GO

Dies ist das Resultset.

ID     Value

------ -----

1      100

2      200

(2 row(s) affected)

-- UPDATE statement with CTE references that are incorrectly matched.
USE tempdb;
GO
DECLARE @x TABLE (ID int, Value int);
DECLARE @y TABLE (ID int, Value int);
INSERT @x VALUES (1, 10), (2, 20);
INSERT @y VALUES (1, 100),(2, 200);

WITH cte AS (SELECT * FROM @x)
UPDATE cte   -- cte is not referenced by the alias.
SET Value = y.Value
FROM cte AS x  -- cte is assigned an alias.
INNER JOIN @y AS y ON y.ID = x.ID; 
SELECT * FROM @x; 
GO

Dies ist das Resultset.

ID     Value

------ -----

1      100

2      100

(2 row(s) affected)

Sperrverhalten

Eine UPDATE-Anweisung ruft immer eine exklusive (X) Sperre für die von ihr geänderte Tabelle ab und hält diese Sperre bis zum Abschluss der Transaktion aufrecht. Bei einer exklusiven Sperre können keine anderen Transaktionen Daten ändern. Sie können Tabellenhinweise angeben, um dieses Standardverhalten für die Dauer der UPDATE-Anweisung zu überschreiben, indem Sie eine andere Sperrmethode angeben. Es wird jedoch empfohlen, dass Hinweise nur von erfahrenen Entwicklern und Datenbankadministratoren und nur als letzte Möglichkeit verwendet werden. Weitere Informationen finden Sie unter Tabellenhinweise (Transact-SQL).

Protokollierungsverhalten

Die UPDATE-Anweisung wird protokolliert; Teilupdates von Datentypen mit umfangreichen Werten, die die **.**WRITE-Klausel verwenden, werden allerdings nur minimal protokolliert. Weitere Informationen finden Sie im vorherigen Abschnitt "Datentypen" unter "Aktualisieren von Datentypen mit umfangreichen Werten".

Sicherheit

Berechtigungen

Für die Zieltabelle sind UPDATE-Berechtigungen erforderlich. SELECT-Berechtigungen sind zum Aktualisieren der Tabelle ebenfalls erforderlich, wenn die UPDATE-Anweisung eine WHERE-Klausel enthält, oder wenn expression in der SET-Klausel eine Spalte in der Tabelle verwendet.

Die UPDATE-Berechtigungen erhalten standardmäßig Mitglieder der festen Serverrolle sysadmin, der festen Datenbankrollen db_owner und db_datawriter und der Tabellenbesitzer. Mitglieder der Rollen sysadmin, db_owner und db_securityadmin sowie der Tabellenbesitzer können Berechtigungen an andere Benutzer übertragen.

Beispiele

Kategorie

Funktionssyntaxelemente

Grundlegende Syntax

UPDATE

Eingrenzen der zu aktualisierenden Zeilen

WHERE • TOP • WITH common table expression • WHERE CURRENT OF

Festlegen von Spaltenwerten

Berechnete Werte • Verbundoperatoren • Standardwerte • Unterabfragen

Angeben von Zielobjekten, die keine Standardtabellen sind

Sichten • Tabellenvariablen • Tabellenaliase

Aktualisieren von Daten auf Grundlage von Daten aus anderen Tabellen

FROM

Aktualisieren von Zeilen in einer Remotetabelle

Verbindungsserver • OPENQUERY • OPENDATASOURCE

Aktualisieren von Large Object-Datentypen

.WRITE • OPENROWSET

Aktualisieren benutzerdefinierter Typen

Benutzerdefinierte Typen

Überschreiben des Standardverhaltens des Abfrageoptimierers mithilfe von Hinweisen

Tabellenhinweise • Abfragehinweise

Erfassen der Ergebnisse der UPDATE-Anweisung

OUTPUT-Klausel

Verwenden von UPDATE in anderen Anweisungen

Gespeicherte Prozeduren • TRY…CATCH

Grundlegende Syntax

Anhand von Beispielen in diesem Abschnitt wird die grundlegende Funktion der UPDATE-Anweisung mithilfe der mindestens erforderlichen Syntax veranschaulicht.

A.Verwenden einer einfachen UPDATE-Anweisung

Im folgenden Beispiel wird eine einzelne Spalte für alle Zeilen in der Person.Address-Tabelle aktualisiert.

USE AdventureWorks2012;
GO
UPDATE Person.Address
SET ModifiedDate = GETDATE();

B.Aktualisieren mehrerer Spalten

Im folgenden Beispiel werden die Werte in den Spalten Bonus, CommissionPct und SalesQuota für alle Zeilen in der SalesPerson-Tabelle aktualisiert.

USE AdventureWorks2012;
GO
UPDATE Sales.SalesPerson
SET Bonus = 6000, CommissionPct = .10, SalesQuota = NULL;
GO

Eingrenzen der zu aktualisierenden Zeilen

Die Beispiele in diesem Abschnitt veranschaulichen Methoden, mit denen die Anzahl der von der UPDATE-Anweisung betroffenen Zeilen eingegrenzt werden kann.

A.Verwenden der WHERE-Klausel

Im folgenden Beispiel wird die WHERE-Klausel verwendet, um die zu aktualisierenden Zeilen anzugeben. Die Anweisung aktualisiert den Wert in der Spalte Color der Tabelle Production.Product für alle Zeilen, die in der Spalte Color den vorhandenen Wert "Red" aufweisen und einen Wert in der Spalte Name aufweisen, der mit "Road-250" beginnt.

USE AdventureWorks2012;
GO
UPDATE Production.Product
SET Color = N'Metallic Red'
WHERE Name LIKE N'Road-250%' AND Color = N'Red';
GO

B.Verwenden der TOP-Klausel

In den folgenden Beispielen wird mithilfe der TOP-Klausel die Anzahl der Zeilen beschränkt, die in einer UPDATE-Anweisung geändert werden. Wenn eine TOP (n)-Klausel zusammen mit UPDATE verwendet wird, wird der Updatevorgang für eine zufällige Auswahl von n Zeilen ausgeführt. Im folgenden Beispiel wird die VacationHours-Spalte um 25 Prozent für 10 zufällige Zeilen in der Employee-Tabelle aktualisiert.

USE AdventureWorks2012;
GO
UPDATE Production.Product
SET Color = N'Metallic Red'
WHERE Name LIKE N'Road-250%' AND Color = N'Red';
GO

Wenn TOP verwendet werden muss, um Updates in einer sinnvollen Abfolge anzuwenden, muss in einer untergeordneten SELECT-Anweisung TOP gemeinsam mit ORDER BY verwendet werden. Mit dem nachfolgenden Beispiel werden die Urlaubsstunden der 10 Mitarbeiter mit dem frühesten Einstellungsdatum aktualisiert.

UPDATE HumanResources.Employee
SET VacationHours = VacationHours + 8
FROM (SELECT TOP 10 BusinessEntityID FROM HumanResources.Employee
     ORDER BY HireDate ASC) AS th
WHERE HumanResources.Employee.BusinessEntityID = th.BusinessEntityID;
GO

C.Verwenden der WITH common_table_expression-Klausel

Im folgenden Beispiel wird der PerAssemnblyQty-Wert für alle Teile und Komponenten aktualisiert, die direkt oder indirekt zum Erstellen der ProductAssemblyID 800 verwendet werden. Der allgemeine Tabellenausdruck gibt eine hierarchische Liste mit Teilen zurück, die zum Erstellen der ProductAssemblyID 800 direkt verwendet werden, sowie mit Teilen, die zum Erstellen dieser Komponenten verwendet werden, usw. Nur die Zeilen, die vom allgemeinen Tabellenausdruck zurückgegeben werden, werden geändert.

USE AdventureWorks2012;
GO
WITH Parts(AssemblyID, ComponentID, PerAssemblyQty, EndDate, ComponentLevel) AS
(
    SELECT b.ProductAssemblyID, b.ComponentID, b.PerAssemblyQty,
        b.EndDate, 0 AS ComponentLevel
    FROM Production.BillOfMaterials AS b
    WHERE b.ProductAssemblyID = 800
          AND b.EndDate IS NULL
    UNION ALL
    SELECT bom.ProductAssemblyID, bom.ComponentID, p.PerAssemblyQty,
        bom.EndDate, ComponentLevel + 1
    FROM Production.BillOfMaterials AS bom 
        INNER JOIN Parts AS p
        ON bom.ProductAssemblyID = p.ComponentID
        AND bom.EndDate IS NULL
)
UPDATE Production.BillOfMaterials
SET PerAssemblyQty = c.PerAssemblyQty * 2
FROM Production.BillOfMaterials AS c
JOIN Parts AS d ON c.ProductAssemblyID = d.AssemblyID
WHERE d.ComponentLevel = 0; 

D.Verwenden der WHERE CURRENT OF-Klausel

Im folgenden Beispiel wird die WHERE CURRENT OF-Klausel verwendet, um nur die Zeile zu aktualisieren, auf der der Cursor positioniert ist. Wenn ein Cursor auf einem Join basiert, wird nur die Tabelle geändert, die mit table_name in der UPDATE-Anweisung angegeben wurde. Andere im Cursor enthaltene Tabellen sind davon nicht betroffen.

USE AdventureWorks2012;
GO
DECLARE complex_cursor CURSOR FOR
    SELECT a.BusinessEntityID
    FROM HumanResources.EmployeePayHistory AS a
    WHERE RateChangeDate <> 
         (SELECT MAX(RateChangeDate)
          FROM HumanResources.EmployeePayHistory AS b
          WHERE a.BusinessEntityID = b.BusinessEntityID) ;
OPEN complex_cursor;
FETCH FROM complex_cursor;
UPDATE HumanResources.EmployeePayHistory
SET PayFrequency = 2 
WHERE CURRENT OF complex_cursor;
CLOSE complex_cursor;
DEALLOCATE complex_cursor;
GO

Festlegen von Spaltenwerten

Die Beispiele in diesem Abschnitt veranschaulichen das Update von Spalten mithilfe von berechneten Werten, Unterabfragen und DEFAULT-Werten.

A.Angeben eines berechneten Werts

In den folgenden Beispielen werden berechnete Werte in einer UPDATE-Anweisung verwendet. In diesem Beispiel wird der Wert in der ListPrice-Spalte für alle Zeilen in der Product-Tabelle verdoppelt.

USE AdventureWorks2012 ;
GO
UPDATE Production.Product
SET ListPrice = ListPrice * 2;
GO

B.Angeben eines Verbundoperators

Im folgenden Beispiel wird die @NewPrice-Variable verwendet, um den Preis aller roten Fahrräder zu erhöhen, indem zum aktuellen Preis der Wert 10 addiert wird.

USE AdventureWorks2012;
GO
DECLARE @NewPrice int = 10;
UPDATE Production.Product
SET ListPrice += @NewPrice
WHERE Color = N'Red';
GO

Im folgenden Beispiel werden mithilfe des Verbundoperators += die ' - tool malfunction'-Daten an den vorhandenen Wert in der Spalte Name für Zeilen mit einer ScrapReasonID zwischen 10 und 12 angefügt.

USE AdventureWorks2012;
GO
UPDATE Production.ScrapReason 
SET Name += ' - tool malfunction'
WHERE ScrapReasonID BETWEEN 10 and 12;

C.Angeben einer Unterabfrage in der SET-Klausel

Im folgenden Beispiel wird mit einer Unterabfrage in der SET-Klausel der Wert bestimmt, der zum Aktualisieren der Spalte verwendet wird. Die Unterabfrage muss nur einen Skalarwert (d. h. einen einzelnen Wert pro Zeile) zurückgeben. In diesem Beispiel wird die Spalte SalesYTD in der SalesPerson-Tabelle geändert, um die neuesten Verkaufszahlen in der SalesOrderHeader-Tabelle wiederzugeben. Die Unterabfrage aggregiert die Umsätze für jeden Vertriebsmitarbeiter in der UPDATE-Anweisung.

USE AdventureWorks2012;
GO
UPDATE Sales.SalesPerson
SET SalesYTD = SalesYTD + 
    (SELECT SUM(so.SubTotal) 
     FROM Sales.SalesOrderHeader AS so
     WHERE so.OrderDate = (SELECT MAX(OrderDate)
                           FROM Sales.SalesOrderHeader AS so2
                           WHERE so2.SalesPersonID = so.SalesPersonID)
     AND Sales.SalesPerson.BusinessEntityID = so.SalesPersonID
     GROUP BY so.SalesPersonID);
GO

D.Aktualisieren von Zeilen mit DEFAULT-Werten

Im folgenden Beispiel wird die Spalte CostRate auf den Standardwert (0.00) für alle Zeilen festgelegt, die über einen CostRate-Wert größer als 20.00 verfügen.

USE AdventureWorks2012;
GO
UPDATE Production.Location
SET CostRate = DEFAULT
WHERE CostRate > 20.00;

Angeben von Zielobjekten, die keine Standardtabellen sind

In den Beispielen in diesem Abschnitt wird veranschaulicht, wie Zeilen durch Angeben einer Sicht, eines Tabellenalias oder einer Tabellenvariablen aktualisiert werden.

A.Angeben einer Sicht als Zielobjekt

Im folgenden Beispiel werden Zeilen in einer Tabelle aktualisiert, indem eine Sicht als Zielobjekt angegeben wird. Die Sichtdefinition verweist auf mehrere Tabellen, die UPDATE-Anweisung wird jedoch erfolgreich ausgeführt, da sie auf Spalten nur von einer der zugrunde liegenden Tabellen verweist. Die UPDATE-Anweisung würde fehlschlagen, wenn Spalten von beiden Tabellen angegeben wären. Weitere Informationen finden Sie unter Ändern von Daten über eine Sicht.

USE AdventureWorks2012;
GO
UPDATE Person.vStateProvinceCountryRegion
SET CountryRegionName = 'United States of America'
WHERE CountryRegionName = 'United States';

B.Angeben eines Tabellenalias als Zielobjekt

Im folgenden Beispiel werden Zeilen in der Tabelle Production.ScrapReason aktualisiert. Der ScrapReason in der FROM-Klausel zugewiesene Tabellenalias wird als Zielobjekt in der UPDATE-Klausel angegeben.

USE AdventureWorks2012;
GO
UPDATE sr
SET sr.Name += ' - tool malfunction'
FROM Production.ScrapReason AS sr
JOIN Production.WorkOrder AS wo 
     ON sr.ScrapReasonID = wo.ScrapReasonID
     AND wo.ScrappedQty > 300;

C.Angeben einer Tabellenvariablen als Zielobjekt

Im folgenden Beispiel werden Zeilen in einer Tabellenvariablen aktualisiert.

USE AdventureWorks2012;
GO
-- Create the table variable.
DECLARE @MyTableVar table(
    EmpID int NOT NULL,
    NewVacationHours int,
    ModifiedDate datetime);

-- Populate the table variable with employee ID values from HumanResources.Employee.
INSERT INTO @MyTableVar (EmpID)
    SELECT BusinessEntityID FROM HumanResources.Employee;

-- Update columns in the table variable.
UPDATE @MyTableVar
SET NewVacationHours = e.VacationHours + 20,
    ModifiedDate = GETDATE()
FROM HumanResources.Employee AS e 
WHERE e.BusinessEntityID = EmpID;

-- Display the results of the UPDATE statement.
SELECT EmpID, NewVacationHours, ModifiedDate FROM @MyTableVar
ORDER BY EmpID;
GO

Aktualisieren von Daten auf Grundlage von Daten aus anderen Tabellen

Anhand von Beispielen in diesem Abschnitt werden Methoden zum Aktualisieren von Zeilen auf Grundlage von Informationen in einer anderen Tabelle gezeigt.

A.Verwenden der UPDATE-Anweisung mit Informationen aus einer anderen Tabelle

Im folgenden Beispiel wird die SalesYTD in der SalesPerson-Tabelle geändert, um die neuesten Verkaufszahlen in der SalesOrderHeader-Tabelle wiederzugeben.

USE AdventureWorks2012;
GO
UPDATE Sales.SalesPerson
SET SalesYTD = SalesYTD + SubTotal
FROM Sales.SalesPerson AS sp
JOIN Sales.SalesOrderHeader AS so
    ON sp.BusinessEntityID = so.SalesPersonID
    AND so.OrderDate = (SELECT MAX(OrderDate)
                        FROM Sales.SalesOrderHeader
                        WHERE SalesPersonID = sp.BusinessEntityID);
GO

Im vorherigen Beispiel wird angenommen, dass nur ein Verkauf für einen angegebenen Verkäufer an einem bestimmten Datum aufgezeichnet wird und Updates aktuell sind. Wenn mehr als ein Verkauf für einen angegebenen Verkäufer am selben Tag gespeichert werden kann, funktioniert das gezeigte Beispiel nicht richtig. Das Beispiel wird zwar fehlerlos ausgeführt, jeder SalesYTD -Wert wird jedoch mit nur einem Verkauf aktualisiert. Dies ist unabhängig davon, wie viele Verkäufe an diesem Tag tatsächlich stattgefunden haben. Die Ursache ist darin zu suchen, dass eine einzelne UPDATE-Anweisung dieselbe Zeile nicht zweimal ändern kann.

Wenn für einen angegebenen Vertriebsmitarbeiter mehrere Verkäufe pro Tag möglich sind, müssen sämtliche Verkäufe der einzelnen Vertriebsmitarbeiter mithilfe der UPDATE-Anweisung aggregiert werden, wie im nachfolgenden Beispiel dargestellt:

USE AdventureWorks2012;
GO
UPDATE Sales.SalesPerson
SET SalesYTD = SalesYTD + 
    (SELECT SUM(so.SubTotal) 
     FROM Sales.SalesOrderHeader AS so
     WHERE so.OrderDate = (SELECT MAX(OrderDate)
                           FROM Sales.SalesOrderHeader AS so2
                           WHERE so2.SalesPersonID = so.SalesPersonID)
     AND Sales.SalesPerson.BusinessEntityID = so.SalesPersonID
     GROUP BY so.SalesPersonID);
GO

Aktualisieren von Zeilen in einer Remotetabelle

In den Beispielen in diesem Abschnitt wird veranschaulicht, wie Zeilen in einer Remotezieltabelle mit einem Verbindungsserver oder einer Rowsetfunktion aktualisiert werden, um auf die Remotetabelle zu verweisen.

A.Aktualisieren von Daten in einer Remotetabelle mithilfe eines Verbindungsservers

Im folgenden Beispiel wird eine Tabelle auf einem Remoteserver aktualisiert. In diesem Beispiel wird zunächst mithilfe von sp_addlinkedserver ein Link zur Remotedatenquelle erstellt. Der Name des Verbindungsservers (MyLinkServer) wird anschließend als Teil des vierteiligen Objektnamens in der Form server.catalog.schema.object angegeben. Beachten Sie, dass Sie einen gültigen Servernamen für @datasrc angeben müssen.

USE master;
GO
-- Create a link to the remote data source. 
-- Specify a valid server name for @datasrc as 'server_name' or 'server_name\instance_name'.

EXEC sp_addlinkedserver @server = N'MyLinkServer',
    @srvproduct = N' ',
    @provider = N'SQLNCLI10', 
    @datasrc = N'<server name>',
    @catalog = N'AdventureWorks2012';
GO
USE AdventureWorks2012;
GO
-- Specify the remote data source using a four-part name 
-- in the form linked_server.catalog.schema.object.

UPDATE MyLinkServer.AdventureWorks2012.HumanResources.Department
SET GroupName = N'Public Relations'
WHERE DepartmentID = 4;

B.Aktualisieren von Daten in einer Remotetabelle mithilfe der OPENQUERY-Funktion

Im folgenden Beispiel wird durch Angabe der OPENQUERY-Rowsetfunktion eine Zeile in einer Remotetabelle aktualisiert. Der im vorherigen Beispiel erstellte Name des Verbindungsservers wird hier verwendet.

UPDATE OPENQUERY (MyLinkServer, 'SELECT GroupName FROM HumanResources.Department WHERE DepartmentID = 4') 
SET GroupName = 'Sales and Marketing';

C.Aktualisieren von Daten in einer Remotetabelle mithilfe der OPENDATASOURCE-Funktion

Im folgenden Beispiel wird durch Angabe der OPENDATASOURCE-Rowsetfunktion eine Zeile in eine Remotetabelle eingefügt. Geben Sie mit dem Format server_name oder server_name\instance_name einen gültigen Servernamen für die Datenquelle an. Sie müssen möglicherweise die Instanz von SQL Server für "Ad Hoc Distributed Queries" konfigurieren. Weitere Informationen finden Sie unter Ad Hoc Distributed Queries (Serverkonfigurationsoption).

UPDATE OPENQUERY (MyLinkServer, 'SELECT GroupName FROM HumanResources.Department WHERE DepartmentID = 4') 
SET GroupName = 'Sales and Marketing';

Aktualisieren von Large Object-Datentypen

Anhand von Beispielen in diesem Abschnitt werden Methoden zum Aktualisieren von Werten in Spalten gezeigt, die mit LOB-Datentypen (Large Object) definiert sind.

A.Verwenden von UPDATE mit .WRITE zum Ändern von Daten in einer nvarchar(max)-Spalte

Im folgenden Beispiel wird die .WRITE-Klausel verwendet, um einen Teilwert in DocumentSummary zu aktualisieren, einer nvarchar(max)-Spalte in der Production.Document -Tabelle. Das Wort components wird durch das Wort features ersetzt. Dazu werden das Ersetzungswort, die Anfangsposition (Offset) des zu ersetzenden Worts in den vorhandenen Daten und die Anzahl von zu ersetzenden Zeichen (Länge) angegeben. Im Beispiel wird außerdem die OUTPUT-Klausel zur Rückgabe der Anfangs- und Endimages der Spalte DocumentSummary an die @MyTableVar-Tabellenvariable verwendet.

USE AdventureWorks2012;
GO
DECLARE @MyTableVar table (
    SummaryBefore nvarchar(max),
    SummaryAfter nvarchar(max));
UPDATE Production.Document
SET DocumentSummary .WRITE (N'features',28,10)
OUTPUT deleted.DocumentSummary, 
       inserted.DocumentSummary 
    INTO @MyTableVar
WHERE Title = N'Front Reflector Bracket Installation';
SELECT SummaryBefore, SummaryAfter 
FROM @MyTableVar;
GO

B.Verwenden von UPDATE mit .WRITE zum Hinzufügen und Entfernen von Daten in einer nvarchar(max)-Spalte

In den folgenden Beispielen werden Daten einer nvarchar(max)-Spalte hinzugefügt bzw. daraus entfernt, die einen Wert hat, der zurzeit auf NULL festgelegt ist. Da die .WRITE-Klausel nicht zum Ändern einer NULL-Spalte verwendet werden kann, wird die Spalte zuerst mit temporären Daten aufgefüllt. Anschließend werden diese Daten mithilfe der .WRITE-Klausel durch die richtigen Daten ersetzt. In den zusätzlichen Beispielen werden am Ende des Spaltenwerts Daten angefügt, Daten (durch Abschneiden) aus der Spalte entfernt und schließlich Teildaten aus der Spalte entfernt. Die SELECT-Anweisungen zeigen die Datenänderung an, die von jeder UPDATE-Anweisung generiert wurde.

USE AdventureWorks2012;
GO
-- Replacing NULL value with temporary data.
UPDATE Production.Document
SET DocumentSummary = N'Replacing NULL value'
WHERE Title = N'Crank Arm and Tire Maintenance';
GO
SELECT DocumentSummary 
FROM Production.Document
WHERE Title = N'Crank Arm and Tire Maintenance';
GO
-- Replacing temporary data with the correct data. Setting @Length to NULL 
-- truncates all existing data from the @Offset position.
UPDATE Production.Document
SET DocumentSummary .WRITE(N'Carefully inspect and maintain the tires and crank arms.',0,NULL)
WHERE Title = N'Crank Arm and Tire Maintenance';
GO
SELECT DocumentSummary 
FROM Production.Document
WHERE Title = N'Crank Arm and Tire Maintenance';
GO
-- Appending additional data to the end of the column by setting 
-- @Offset to NULL.
UPDATE Production.Document
SET DocumentSummary .WRITE (N' Appending data to the end of the column.', NULL, 0)
WHERE Title = N'Crank Arm and Tire Maintenance';
GO
SELECT DocumentSummary 
FROM Production.Document
WHERE Title = N'Crank Arm and Tire Maintenance';
GO
-- Removing all data from @Offset to the end of the existing value by 
-- setting expression to NULL. 
UPDATE Production.Document
SET DocumentSummary .WRITE (NULL, 56, 0)
WHERE Title = N'Crank Arm and Tire Maintenance';
GO
SELECT DocumentSummary 
FROM Production.Document
WHERE Title = N'Crank Arm and Tire Maintenance';
GO
-- Removing partial data beginning at position 9 and ending at 
-- position 21.
UPDATE Production.Document
SET DocumentSummary .WRITE ('',9, 12)
WHERE Title = N'Crank Arm and Tire Maintenance';
GO
SELECT DocumentSummary 
FROM Production.Document
WHERE Title = N'Crank Arm and Tire Maintenance';
GO

C.Verwenden von UPDATE mit OPENROWSET zum Ändern einer varbinary(max)-Spalte

Im folgenden Beispiel wird ein vorhandenes Image, das in einer varbinary(max)-Spalte gespeichert ist, durch ein neues Image ersetzt. Die OPENROWSET-Funktion wird mit der BULK-Option verwendet, um das Image in die Spalte zu laden. In diesem Beispiel wird angenommen, dass eine Datei namens Tires.jpg im angegebenen Dateipfad vorhanden ist.

USE AdventureWorks2012;
GO
UPDATE Production.ProductPhoto
SET ThumbNailPhoto = (
    SELECT *
    FROM OPENROWSET(BULK 'c:\Tires.jpg', SINGLE_BLOB) AS x )
WHERE ProductPhotoID = 1;
GO

D.Verwenden von UPDATE zum Ändern von FILESTREAM-Daten

Im folgenden Beispiel wird die UPDATE-Anweisung zum Ändern der Daten in der Dateisystemdatei verwendet. Diese Methode wird nicht zum Streamen von großen Datenmengen in eine Datei empfohlen. Verwenden Sie die entsprechenden Win32-Schnittstellen. Im folgenden Beispiel wird der gesamte Text im Dateidatensatz durch den Text Xray 1 ersetzt. Weitere Informationen finden Sie unter FILESTREAM (SQL Server).

UPDATE Archive.dbo.Records
SET [Chart] = CAST('Xray 1' as varbinary(max))
WHERE [SerialNumber] = 2;

Aktualisieren benutzerdefinierter Typen

In den folgenden Beispielen werden Werte in Spalten eines CLR-benutzerdefinierten Typs (UDT) geändert. Es werden drei Methoden gezeigt. Weitere Informationen zu benutzerdefinierten Spalten finden Sie unter Benutzerdefinierte CLR-Typen.

A.Verwenden eines Systemdatentyps

Sie können einen UDT durch Bereitstellen eines Werts eines SQL Server-Systemdatentyps aktualisieren, sofern der benutzerdefinierte Typ implizite oder explizite Konvertierung von diesem Typ unterstützt. Im folgenden Beispiel wird gezeigt, wie Sie einen Wert in einer Spalte des benutzerdefinierten Typs Point durch explizites Konvertieren aus einer Zeichenfolge aktualisieren.

UPDATE dbo.Cities
SET Location = CONVERT(Point, '12.3:46.2')
WHERE Name = 'Anchorage';

B.Aufrufen einer Methode

Sie können einen UDT durch Aufrufen einer Methode des benutzerdefinierten Typs, die als Mutator markiert ist, aktualisieren, um das Update auszuführen. Im folgenden Beispiel wird eine Mutatormethode des Typs Point namens SetXY aufgerufen. Dadurch wird der Status der Instanz des Typs aktualisiert.

UPDATE dbo.Cities
SET Location.SetXY(23.5, 23.5)
WHERE Name = 'Anchorage';

C.Ändern des Werts einer Eigenschaft oder eines Datenelements

Sie können einen UDT durch Ändern des Werts eines Elements einer registrierten Eigenschaft oder öffentlicher Daten des benutzerdefinierten Typs aktualisieren. Der Ausdruck, der den Wert bereitstellt, muss implizit in den Typ der Eigenschaft konvertierbar sein. Im folgenden Beispiel wird der Wert der X-Eigenschaft des benutzerdefinierten Typs Point geändert.

UPDATE dbo.Cities
SET Location.X = 23.5
WHERE Name = 'Anchorage';

Überschreiben des Standardverhaltens des Abfrageoptimierers mithilfe von Hinweisen

In den Beispielen in diesem Abschnitt wird gezeigt, wie mit Tabellen- und Abfragehinweisen beim Verarbeiten der UPDATE-Anweisung zeitweise das Standardverhalten des Abfrageoptimierers überschrieben wird.

Warnung

Da der SQL Server-Abfrageoptimierer in der Regel den optimalen Ausführungsplan für eine Abfrage auswählt, wird empfohlen, dass erfahrene Entwickler und Datenbankadministratoren Hinweise nur dann verwenden, wenn alle anderen Möglichkeiten sich als unzureichend erwiesen haben.

A.Angeben eines Tabellenhinweises

Im folgenden Beispiel wird der Tabellenhinweis TABLOCK angegeben. Dieser Hinweis gibt an, dass eine gemeinsame Sperre für die Tabelle Production.Product eingerichtet und bis zum Ende der UPDATE-Anweisung aufrechterhalten wird.

USE AdventureWorks2012;
GO
UPDATE Production.Product
WITH (TABLOCK)
SET ListPrice = ListPrice * 1.10
WHERE ProductNumber LIKE 'BK-%';
GO

B.Angeben eines Abfragehinweises

Im folgenden Beispiel wird der Abfragehinweis OPTIMIZE FOR (@variable) in der UPDATE-Anweisung angegeben. Dieser Hinweis weist den Abfrageoptimierer an, einen bestimmten Wert für eine lokale Variable zu verwenden, wenn die Abfrage kompiliert und optimiert wird. Dieser Wert wird nur während der Abfrageoptimierung verwendet, nicht während der Abfrageausführung.

USE AdventureWorks2012;
GO
CREATE PROCEDURE Production.uspProductUpdate
@Product nvarchar(25)
AS
SET NOCOUNT ON;
UPDATE Production.Product
SET ListPrice = ListPrice * 1.10
WHERE ProductNumber LIKE @Product
OPTION (OPTIMIZE FOR (@Product = 'BK-%') );
GO
-- Execute the stored procedure 
EXEC Production.uspProductUpdate 'BK-%';

Erfassen der Ergebnisse der UPDATE-Anweisung

In den Beispielen in diesem Abschnitt wird gezeigt, wie mit der OUTPUT-Klausel Informationen aus jeder von einer UPDATE-Anweisung betroffenen Zeile bzw. Ausdrücke, die auf jeder Zeile basieren, zurückgegeben werden. Diese Ergebnisse können an die verarbeitende Anwendung zurückgegeben werden, die sie z. B. für Bestätigungen, Archivierungen und andere Anwendungsanforderungen verwendet.

A.Verwenden von UPDATE mit der OUTPUT-Klausel

Im folgenden Beispiel wird die Spalte VacationHours in der Tabelle Employee um 25 Prozent für die ersten 10 Zeilen aktualisiert und außerdem der Wert in der Spalte ModifiedDate auf das aktuelle Datum festgelegt. Die OUTPUT-Klausel gibt an die @MyTableVar-Tabellenvariable den Wert für VacationHours zurück, der vor der Anwendung der UPDATE-Anweisung in der deleted.VacationHours-Spalte vorhanden war, und den aktualisierten Wert in der inserted.VacationHours-Spalte.

Es folgen zwei SELECT-Anweisungen, die die Werte in @MyTableVar und die Ergebnisse des Updatevorgangs in der Employee-Tabelle zurückgeben. Weitere Beispiele zum Verwenden der OUTPUT-Klausel finden Sie unter OUTPUT-Klausel (Transact-SQL).

USE AdventureWorks2012;
GO
DECLARE @MyTableVar table(
    EmpID int NOT NULL,
    OldVacationHours int,
    NewVacationHours int,
    ModifiedDate datetime);
UPDATE TOP (10) HumanResources.Employee
SET VacationHours = VacationHours * 1.25,
    ModifiedDate = GETDATE() 
OUTPUT inserted.BusinessEntityID,
       deleted.VacationHours,
       inserted.VacationHours,
       inserted.ModifiedDate
INTO @MyTableVar;
--Display the result set of the table variable.
SELECT EmpID, OldVacationHours, NewVacationHours, ModifiedDate
FROM @MyTableVar;
GO
--Display the result set of the table.
SELECT TOP (10) BusinessEntityID, VacationHours, ModifiedDate
FROM HumanResources.Employee;
GO

Verwenden von UPDATE in anderen Anweisungen

In Beispielen in diesem Abschnitt wird die Verwendung von UPDATE in anderen Anweisungen veranschaulicht.

A.Verwenden von UPDATE in einer gespeicherten Prozedur

Im folgenden Beispiel wird eine UPDATE-Anweisung in einer gespeicherten Prozedur verwendet. Die Prozedur erfordert den Eingabeparameter @NewHours und den Ausgabeparameter @RowCount. Der @NewHours -Parameterwert wird in der UPDATE-Anweisung verwendet, um die Spalte VacationHours in der Tabelle HumanResources.Employee zu aktualisieren. Der Ausgabeparameter @RowCount wird verwendet, um die Anzahl betroffener Zeilen an eine lokale Variable zurückzugeben. Der CASE-Ausdruck wird in der SET-Klausel verwendet, um den Wert, der für VacationHours festgelegt wird, bedingt zu bestimmen. Wenn der Mitarbeiter pro Stunde bezahlt wird (SalariedFlag = 0), ist VacationHours auf die aktuelle Anzahl der Stunden zuzüglich des Werts festgelegt, der unter @NewHours angegeben ist. Andernfalls ist VacationHours auf den Wert festgelegt, der unter @NewHours angegeben ist.

USE AdventureWorks2012;
GO
CREATE PROCEDURE HumanResources.Update_VacationHours
@NewHours smallint
AS 
SET NOCOUNT ON;
UPDATE HumanResources.Employee
SET VacationHours = 
    ( CASE
         WHEN SalariedFlag = 0 THEN VacationHours + @NewHours
         ELSE @NewHours
       END
    )
WHERE CurrentFlag = 1;
GO

EXEC HumanResources.Update_VacationHours 40;

B.Verwenden von UPDATE in einem TRY…CATCH-Block

Im folgenden Beispiel wird eine UPDATE-Anweisung in einem TRY…CATCH-Block verwendet, um Ausführungsfehler zu behandeln, die während des Updatevorgangs auftreten können.

USE AdventureWorks2012;
GO
BEGIN TRANSACTION;

BEGIN TRY
    -- Intentionally generate a constraint violation error.
    UPDATE HumanResources.Department
    SET Name = N'MyNewName'
    WHERE DepartmentID BETWEEN 1 AND 2;
END TRY
BEGIN CATCH
    SELECT 
         ERROR_NUMBER() AS ErrorNumber
        ,ERROR_SEVERITY() AS ErrorSeverity
        ,ERROR_STATE() AS ErrorState
        ,ERROR_PROCEDURE() AS ErrorProcedure
        ,ERROR_LINE() AS ErrorLine
        ,ERROR_MESSAGE() AS ErrorMessage;

    IF @@TRANCOUNT > 0
        ROLLBACK TRANSACTION;
END CATCH;

IF @@TRANCOUNT > 0
    COMMIT TRANSACTION;
GO

Siehe auch

Verweis

CREATE TABLE (SQL Server)

CREATE TRIGGER (Transact-SQL)

Cursor (Transact-SQL)

DELETE (Transact-SQL)

INSERT (Transact-SQL)

Text- und Bildfunktionen (Transact-SQL)

WITH common_table_expression (Transact-SQL)

Konzepte

FILESTREAM (SQL Server)