Ist `Delete From Join` Standard SQL?

Unter anderem hat man gefragt, wie man aus einem beitrag zu löschen

Meine Frage: Wie viel davon ist Standard SQL? Auf welche databaseen würde das eigentlich funktionieren (vor allem für mich wäre Oracle, MySQL und SQLserver)?

   

DELETE … FROM .. ist nicht Teil der ANSI-Standards, noch UPDATE … FROM … für diese Angelegenheit. Dies schließt jede Join-Syntax ein, da die Verknüpfung nur mit einem FROM angegeben werden kann.

Alle Anbieter implementieren dies in der einen oder anderen Form.

Nicht Standard nach internationaler Norm ISO / IEC 9075: 1992 Abschnitt 13.6, Seiten 384-386. Löschen mit JOIN-Syntax funktioniert nicht in Oracle.

das wird eigentlich in Oracle funktionieren. Das FROM-Schlüsselwort ist optional: DELETE (query) ist das gleiche wie DELETE FROM (query) .

Die Regeln zum LÖSCHEN EINER JOIN sind die gleichen wie die Regeln, um eine JOIN zu aktualisieren: Oracle wird die Zeilen aus nur einer Tabelle ändern und nur dann, wenn es keine Zweideutigkeiten bei der Identifizierung der Zeilen der Basistabelle gibt. Schau in diese SO oder diese SO zum Beispiel.

Lassen Sie uns ein kleines Beispiel build:

 CREATE TABLE t_parent (ID NUMBER PRIMARY KEY, NAME VARCHAR2(10)); CREATE TABLE t_child (ID NUMBER PRIMARY KEY, parent_id NUMBER REFERENCES t_parent); INSERT INTO t_parent VALUES (1, 'a'); INSERT INTO t_child VALUES (1, 1); INSERT INTO t_child VALUES (2, 1); 

Sie können Zeilen aus der KIND-Tabelle löschen:

 SQL> DELETE FROM (SELECT t_child.* 2 FROM t_child 3 JOIN t_parent ON t_parent.id = t_child.parent_id 4 WHERE t_parent.name = 'a'); 2 rows deleted 

Das letzte Mal sah ich den ANSI-Standard an, die bevorzugte Methode war Unterabfragen und nicht JOINs. Im Umgang mit nur einer Implementierung, wo Portierung Ihr Code ist kein Problem, dann können Sie vendor-spezifische Erweiterungen frei verwenden, wenn sie effizienter sind (obwohl UPDATE FROM, und ich stelle mir vor, DELETE FROM in einigen Szenarien, hat sich als unvorhersehbar erwiesen: http : //sqlblog.com/blogs/hugo_kornelis/archive/2008/03/10/lets-deprecate-update-from.aspx ). Persönlich verwende ich typischerweise CTEs für eine Menge von DELETE-Operationen … aber meine Entwicklung ist auf SQL server beschränkt und ich muss mir nicht viel über Portabilität überhaupt sorgen. MERGE kann auch eine gute Wahl sein, wenn Sie mehrere DML-Operationen durchführen, aber wieder ist dies nicht gleich (oder überhaupt) über alle Anbieter implementiert.

In deinem Fall würde ich sagen, bleib weg von DELETE FROM … JOIN, weil die Syntax auf den drei Plattformen leicht variieren wird. Wenn Sie gespeicherte Prozeduren verwenden, ist dies weniger ein Problem, als wenn das SQL in Ihre Anwendung (en) eingebettet ist, aber trotzdem ein Streit.

Die Standard-SQL-92-Syntax erforderte eine skalare Unterabfrage. Dies ist eine relational solide Lösung, weil es keine Unklarheit gibt (im Gegensatz zu den proprietären Alternativen, die unvorhersehbare / unerwartete Ergebnisse liefern können).

Einer der Nachteile des SQL-92-Ansatzes ist jedoch, dass er ausführlich sein kann und wiederkehrende Konstrukte beinhalten kann

 UPDATE MyTable SET col1 = ( SELECT T.colA FROM OtherTable T WHERE T.ID = MyTable.ID ), col2 = ( SELECT T.colB FROM OtherTable T WHERE T.ID = MyTable.ID ) WHERE EXISTS ( SELECT * FROM OtherTable T WHERE T.ID = MyTable.ID ); 

Die Idee ist, dass der Optimierer die gleiche Unterabfrage erkennen kann, die wiederverwendet wird, aber in der Praxis haben die Anbieter dies typischerweise nicht implementiert.

SQL-99 adressierte diese Ausführlichkeit und Wiederholung durch die Einführung von MERGE , die weiter in SQL: 2003 verfeinert wurde. Es ist interessant, dass heutzutage die Anbieter in der Regel entscheiden, neue Features nach dem Standard-Spezifikation implementieren dann erweitern sie, um die functionen, die sie benötigen, anstatt schreiben ganz Eigentums-Features.

Ich habe ähnliche Abfragen verwendet, als ich auf einem MS SQL server war. Nicht sicher über die anderen.