Firebird Documentation IndexFirebird 2.5 SprachreferenzStatements der Data Manipulation Language (DML) → UPDATE
Firebird Home Firebird Home Zurück: INSERTFirebird Documentation IndexNach oben: Statements der Data Manipulation Language (DML)Weiter: UPDATE OR INSERT

UPDATE

Inhaltsverzeichnis

Verwendung eines Alias
Die SET-Klausel
Die WHERE-Klausel
Die ORDER BY- und ROWS-Klauseln
Die RETURNING-Klausel
Aktualisieren von BLOB-Spalten

Verwendet für:  Ändern von Zeilen in Tabellen und Sichten

Verfügbar in: DSQL, ESQL, PSQL

Syntax: 

   UPDATE target [[AS] alias]
   SET col = newval [, col = newval ...]
   [WHERE {search-conditions | CURRENT OF cursorname}]
   [PLAN plan_items]
   [ORDER BY sort_items]
   [ROWS <m> [TO <n>]]
   [RETURNING <returning_list> [INTO <variables>]]

<returning_list>     ::=  ret_value [, ret_value ...]
<variables>  ::=  :varname [, :varname ...]
       

Tabelle 6.12. Arguments for the UPDATE Statement Parameters

Argument Beschreibung
target Der Name der Tabelle oder Sicht, in der die Datensätze aktualisiert werden
alias Alias für den Tisch oder die Ansicht
col Name oder Alias einer Spalte in der Tabelle oder Sicht
newval Neuer Wert für eine Spalte, die von der Anweisung in der Tabelle oder Sicht aktualisiert werden soll
search-conditions Eine Suchbedingung, die den Satz der zu aktualisierenden Zeilen begrenzt
cursorname Der Name des Cursors, über den die zu aktualisierende Zeile(n) positioniert wird
plan_items Klauseln im Abfrageplan
sort_items Spalten, die in einer ORDER BY-Klausel aufgeführt sind
m, n Integer-Ausdrücke zur Begrenzung der Anzahl der zu aktualisierenden Zeilen
ret_value Ein Wert, der in der RETURNING-Klausel zurückgegeben werden soll
varname Name einer lokalen PSQL-Variablen


Beschreibung: Die Anweisung UPDATE ändert Werte in einer Tabelle oder in einer oder mehreren Tabellen, die einer Sicht zugrunde liegen. Die betroffenen Spalten sind in der Klausel SET angegeben. Die betroffenen Zeilen können durch die Klauseln WHERE und ROWS eingeschränkt sein. Wenn weder WHERE noch ROWS vorhanden ist, werden alle Datensätze in der Tabelle aktualisiert.

Verwendung eines Alias

Wenn Sie einer Tabelle oder einer Ansicht einen Alias zuweisen, muss der Alias verwendet werden, wenn Spalten angegeben werden, und auch in Spaltenreferenzen, die in anderen Klauseln enthalten sind.

Beispiele: 

Korrekte Verwendung:

update Fruit set soort = 'pisang' where ...
update Fruit set Fruit.soort = 'pisang' where ...
update Fruit F set soort = 'pisang' where ...
update Fruit F set F.soort = 'pisang' where ...

Nicht möglich:

update Fruit F set Fruit.soort = 'pisang' where ...

Die SET-Klausel

In der Klausel SET werden die Zuweisungsausdrücke, die die Spalten mit den festzulegenden Werten enthalten, durch Kommata getrennt. In einer Zuweisungsphrase befinden sich Spaltennamen auf der linken Seite und die Werte oder Ausdrücke, die die Zuweisungswerte enthalten, befinden sich auf der rechten Seite. Eine Spalte darf nur einmal in der Klausel SET enthalten sein.

Ein Spaltenname kann in Ausdrücken auf der rechten Seite verwendet werden. Der alte Wert der Spalte wird immer in diesen Werten auf der rechten Seite verwendet, auch wenn der Spalte bereits in der SET-Klausel ein neuer Wert zugewiesen wurde.

Hier ist ein Beispiel: Daten in der TSET-Tabelle:

A B
----
1 0
2 0
            

Die Anweisung

UPDATE tset SET a = 5, b = a
        

ändert die Werte zu

A B
----
5 1
5 2
          

Beachten Sie, dass die alten Werte (1 und 2) verwendet werden, um die Spalte b zu aktualisieren, auch nachdem der Spalte ein neuer Wert zugewiesen wurde (5).

Anmerkung

Dies war nicht immer so. Vor der Version 2.5 erhielten Spalten ihre neuen Werte sofort nach der Zuweisung. Das war jedoch kein standardmäßiges Verhalten, und wurde in Version 2.5 behoben.

Um die Kompatibilität mit Legacy-Code zu erhalten, enthält die Konfigurationsdatei firebird.conf den Parameter OldSetClauseSemantics, der auf True (1) gesetzt werden kann, um das alte, fehlerhafte Verhalten wiederherzustellen. Es ist eine vorübergehende Maßnahme, der Parameter wird in Zukunft entfernt.

Die WHERE-Klausel

Die WHERE-Klausel legt die Bedingungen fest, die die Datensatzgruppe für ein searched update begrenzen.

Wenn in PSQL ein benannter Cursor zum Aktualisieren eines Satzes verwendet wird und die Klausel WHERE CURRENT OF verwendet wird, ist die Aktion auf die Zeile beschränkt, in der sich der Cursor gerade befindet. Dies ist ein positioniertes Update.

Anmerkung

Die Klausel WHERE CURRENT OF ist nur in PSQL verfügbar, da es keine Anweisung zum Erstellen und Bearbeiten eines expliziten Cursors in DSQL gibt. Gesuchte Updates sind natürlich auch in PSQL verfügbar.

Beispiele: 

UPDATE People
  SET firstname = 'Boris'
  WHERE lastname = 'Johnson';

UPDATE employee e
  SET salary = salary * 1.05
  WHERE EXISTS(
         SELECT *
           FROM employee_project ep
           WHERE e.emp_no = ep.emp_no);

UPDATE addresses
  SET city = 'Saint Petersburg', citycode = 'PET'
  WHERE city = 'Leningrad'

UPDATE employees
  SET salary = 2.5 * salary
  WHERE title = 'CEO'
          

Bei String-Literalen, mit denen der Parser Hilfe beim Interpretieren des Zeichensatzes der Daten benötigt, kann die Einführersyntax verwendet werden. Dem Zeichenfolgenliteral ist der Zeichensatzname vorangestellt, dem ein Unterstrich vorangestellt ist:

-- notice the '_' prefix

UPDATE People
SET name = _ISO8859_1 'Hans-Jörg Schäfer'
WHERE id = 53662
          

Das Problem mit dem „instabilen Cursor

In Firebird muss bis zu dieser Version ein Implementierungsfehler geachtet werden, der diese Art von Aktualisierungen betrifft, wenn die WHERE-Bedingungen das IN (select-expr) und die select-expr in der Form SELECT FIRST n oder SELECT ... ROWS vorliegt. Zum Beispiel

UPDATE T
  SET ...
  WHERE ID IN (SELECT FIRST 1 ID FROM T)
          

liebevoll als die „unendliche Update-Schleife“ bekannt, wird fortlaufend Zeilen aktualisieren, immer und immer wieder, bis der Server hängen bleibt.

Quarks wie dieses können sich auf datenverändernde DML-Operationen auswirken, meistens wenn die Auswahlbedingungen eine Unterabfrage betreffen. Fälle wurden gemeldet, bei denen die Sortierreihenfolge die Erwartungen beeinträchtigt, ohne dass eine Unterabfrage erforderlich ist. Dies geschieht, weil DML-Anweisungen in den Ausführungsebenen anstelle eines stabilen „Zielsatzes“ und anschließendem Ausführen der Datenänderungen für jedes gesetzte Element implizite Cursor zum Ausführen der Operationen für die Zeile verwenden, die derzeit die Bedingungen erfüllt, ohne zu wissen, ob diese Zeile zuvor die Bedingung nicht erfüllt hat oder bereits aktualisiert wurde. Also, mit einem einfachen Beispielmuster:

UPDATE T SET <fields> = <values>
  WHERE <conditions>
          

the execution works as:

FOR SELECT <values> FROM T
  WHERE <conditions>
  INTO <tmp_vars> AS CURSOR <cursor>
  DO
    UPDATE T SET <fields> = <tmp_vars>
    WHERE CURRENT OF <cursor>
          

Die Implementierung von Firebird stimmt nicht mit den SQL-Standards überein, nach denen ein stabiles Set eingerichtet werden muss, bevor Daten geändert werden. Versionen von Firebird ab V.3 werden dem Standard entsprechen.

Die ORDER BY- und ROWS-Klauseln

Die Klauseln ORDER BY und ROWS sind nur sinnvoll, wenn sie zusammen verwendet werden. Sie können jedoch auch getrennt verwendet werden.

Wenn ROWS ein Argument m hat, sind die zu aktualisierenden Zeilen auf die ersten m Zeilen beschränkt.

Wichtige Punkte: 

  • Wenn m > der Anzahl der Zeilen, die verarbeitet werden, wird der gesamte Zeilensatz aktualisiert
  • Wenn m = 0, wird keine Zeile aktualisiert
  • Wenn m < 0, tritt ein Fehler auf und die Aktualisierung schlägt fehl

Wenn zwei Argumente verwendet werden, m und n, begrenzt ROWS die Zeilen, die aktualisiert werden, auf Zeilen von m bis n einschließlich. Beide Argumente sind Ganzzahlen und beginnen bei 1.

Wichtige Punkte: 

  • Wenn m > der Anzahl der zu verarbeitenden Zeilen, werden keine Zeilen aktualisiert
  • Wenn n > der Anzahl der Zeilen, werden Zeilen von m bis zum Ende des Satzes werden aktualisiert
  • Wenn m < 1 oder n < 1, tritt ein Fehler auf und das Update schlägt fehl
  • Wenn n = m - 1, werden keine Zeilen aktualisiert.
  • If n < m -1, ein Fehler tritt auf und die Aktualisierung schlägt fehl

ROWS-Beispiel: 

UPDATE employees
SET salary = salary + 50
ORDER BY salary ASC
ROWS 20
          

Die RETURNING-Klausel

Inhaltsverzeichnis

Die INTO-Unterklausel

Eine Anweisung UPDATE mit höchstens einer Zeile kann RETURNING enthalten, um einige Werte aus der aktualisierten Zeile zurückzugeben. RETURNING kann Daten aus jeder Zeile enthalten, nicht zwangsläufig aus der Zeile, die gerade aktualisiert wird. Es kann Literale enthalten, die nicht mit Spalten verknüpft sind, wenn dies erforderlich ist.

Wenn der RETURNING-Satz Daten aus der aktuellen Zeile enthält, melden die zurückgegebenen Werte Änderungen, die in den BEFORE UPDATE Triggern vorgenommen wurden, nicht jedoch in AFTER UPDATE-Triggern.

Die Kontextvariablen OLD.fieldname und NEW.fieldname können als Spaltennamen verwendet werden. Wenn OLD. oder NEW. nicht angegeben ist, sind die zurückgegebenen Spaltenwerte die in NEW..

In DSQL gibt eine Anweisung mit RETURNING immer eine einzelne Zeile zurück. Wenn die Anweisung keine Datensätze aktualisiert, enthalten die zurückgegebenen Werte NULL. Dieses Verhalten kann sich in zukünftigen Firebird-Versionen ändern.

Die INTO-Unterklausel

In PSQL kann die Klausel INTO verwendet werden, um die zurückgegebenen Werte an lokale Variablen zu übergeben. Es ist nicht in DSQL verfügbar. Wenn keine Datensätze aktualisiert werden, wird nichts zurückgegeben, und die in RETURNING angegebenen Variablen behalten ihre vorherigen Werte bei.

Anmerkung

Wenn ein Wert zurückgegeben und einer NEW-Kontextvariablen zugewiesen wird, ist die Verwendung eines Doppelpunktpräfixes nicht zulässig. Dies ist beispielsweise ungültig:

...
into :var1, :var2, :new.id
              

und dies gültig:

...
into :var1, :var2, new.id
              

RETURNING-Beispiel (DSQL): 

UPDATE Scholars
SET firstname = 'Hugh', lastname = 'Pickering'
WHERE firstname = 'Henry' and lastname = 'Higgins'
RETURNING id, old.lastname, new.lastname
          

Aktualisieren von BLOB-Spalten

Das Aktualisieren einer BLOB-Spalte ersetzt immer den gesamten Inhalt. Sogar die BLOB-ID, das „Handle“ welches direkt in der Spalte gespeichert wird, ändert sich. BLOBs können aktualisiert werden wenn:

  1. Die Client-Anwendung mit der Firebird-API spezielle Vorkehrungen für diese Operation getroffen hat. In diesem Fall ist der modus operandi anwendungsspezifisch und außerhalb des Geltungsbereichs dieses Handbuchs.

  2. Der neue Wert eine Textzeichenfolge von höchstens 32767 Byte ist. Bitte beachten Sie: Wenn der Wert kein String-Literal ist, achten Sie auf Verkettungen, da diese die maximale Länge überschreiten können.

  3. Die Quelle selbst eine BLOB-Spalte oder allgemeiner ein Ausdruck ist, der ein BLOB zurückgibt.

  4. Sie die Anweisung INSERT CURSOR verwenden (nur ESQL).

Zurück: INSERTFirebird Documentation IndexNach oben: Statements der Data Manipulation Language (DML)Weiter: UPDATE OR INSERT
Firebird Documentation IndexFirebird 2.5 SprachreferenzStatements der Data Manipulation Language (DML) → UPDATE