Aktualisieren Sie die Ergebnisse einer SELECT-statement

Mit Oracle können Sie die Ergebnisse einer SELECT-statement aktualisieren.

UPDATE (<SELECT Statement>) SET <column_name> = <value> WHERE <column_name> <condition> <value>; 

Ich nehme an, dass dies für das Aktualisieren von Spalten in einer Tabelle basierend auf dem Wert einer übereinstimmenden Zeile in einer anderen Tabelle verwendet werden könnte.

Wie heißt dieses Feature, kann es effizient für große Updates verwendet werden, funktioniert es, wenn SELECT mehrere Tabellen verknüpft, und wenn ja, wie?

Solutions Collecting From Web of "Aktualisieren Sie die Ergebnisse einer SELECT-statement"

Ich habe dafür keinen formulalen Namen gesehen. Die Oracle SQL-reference bezieht sich nur auf das Aktualisieren einer Unterabfrage. Ich neige dazu, es als eine Form der "viewsaktualisierung" zu betrachten, wobei die Unterabfrage in der Inline-view ist.

Ja, es funktioniert, wenn mehrere Tabellen verknüpft sind, aber den Regeln der viewsaktualisierung unterliegen. Dies bedeutet, dass nur eine der Basistabellen der Sicht aktualisiert werden kann, und diese Tabelle muss in der view "Schlüssel beibehalten" werden: dh ihre Zeilen sollten nur einmal in der view erscheinen können. Dazu müssen alle anderen Tabellen in der Sicht (Unterabfrage) über Fremdschlüsseleinschränkungen in der zu aktualisierenden Tabelle referenziert werden.

Einige Beispiele können helfen. Bei Verwendung der Standardtabellen Oracle EMP und DEPT, wobei EMP.EMPNO als Primärschlüssel von EMP definiert ist und EMP.DEPTNO als Fremdschlüssel für DEPT.DEPTNO definiert ist, ist diese Aktualisierung zulässig:

 update (select emp.empno, emp.ename, emp.sal, dept.dname from emp join dept on dept.deptno = emp.deptno ) set sal = sal+100; 

Aber das ist nicht:

 -- DEPT is not "key-preserved" - same DEPT row may appear -- several times in view update (select emp.ename, emp.sal, dept.deptno, dept.dname from emp join dept on dept.deptno = emp.deptno ) set dname = upper(dname); 

Was die Performance betrifft: Der Optimierer wird (muss) die Basistabelle identifizieren, die während des Parsens aktualisiert werden soll, und Joins mit anderen Tabellen werden ignoriert, da sie keinen Einfluss auf das auszuführende Update haben – wie diese AUTOTRACE-Ausgabe zeigt:

 SQL> update (select emp.ename, emp.sal, dept.dname 2 from emp join dept on dept.deptno = emp.deptno 3 ) 4 set sal = sal-1; 33 rows updated. Execution Plan ---------------------------------------------------------- Plan hash value: 1507993178 ------------------------------------------------------------------------------------ | Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time | ------------------------------------------------------------------------------------ | 0 | UPDATE STATEMENT | | 33 | 495 | 3 (0)| 00:00:01 | | 1 | UPDATE | EMP | | | | | | 2 | NESTED LOOPS | | 33 | 495 | 3 (0)| 00:00:01 | | 3 | TABLE ACCESS FULL| EMP | 33 | 396 | 3 (0)| 00:00:01 | |* 4 | INDEX UNIQUE SCAN| SYS_C0010666 | 1 | 3 | 0 (0)| 00:00:01 | ------------------------------------------------------------------------------------ Predicate Information (identified by operation id): --------------------------------------------------- 4 - access("EMP"."DEPTNO"="DEPT"."DEPTNO") 

(Beachten Sie, dass auf die Tabelle DEPT nie zugegriffen wird, obwohl DEPT.DNAME in der Unterabfrage angezeigt wird).

Das Formular, das Sie erwähnen, hat keinen spezifischen Namen AFAIK. Aktualisieren Sie nur das Ergebnis einer Select-statement.

Es gibt ein anderes Formular namens Correlated Update (mit Einzel- oder Mehrfachupdate Update)

 UPDATE TABLE(<SELECT STATEMENT>) <alias> SET <column_name> = ( SELECT <column_name> FROM <table_name> <alias> WHERE <alias.table_name> <condition> <alias.table_name> ); 

Die mehrspaltige Form

 ... SET (<column_name_list>) = ( SELECT <column_name_list> ... 

Es gibt auch eine, von der auch die Werte mit dem Namen Update mit Rückgabe-Klausel zurückgegeben werden

Und einige Besonderheiten für Updates mit geschachtelten Tabellen. Am besten ist es, mindestens diese zwei Seiten zu überprüfen

Oracle® database SQL-Sprachreferenz SELECT

Oracle® Database SQL-Sprachenreferenz UPDATE

Danke für Kommentare, ich dachte, das war Standard Sql … 🙁

Für Oracle können Sie ein Update für eine Tabelle schreiben, in der Sie Informationen mit einem Join wie:

 UPDATE ( SELECT * FROM table1 t1 LEFT JOIN table2 t2 ON t2.t1id = t1.ID ) SET t1.col1 = t2.col2 

Für Sql server ist es:

 UPDATE t1 SET col1 = t2.col2 FROM table1 t1 LEFT JOIN table2 t2 on t2.t1id = t1.id 

Wenn irgendjemand einen path kennt, dies auf Oracle, Sql server und MySql zu tun, wäre ich interessiert.