it-swarm.com.de

Wie lösche ich mithilfe von INNER JOIN in SQL Server mehrere Tabellen?

In MySQL können Sie die Syntax verwenden

DELETE t1,t2 
FROM table1 AS t1 
INNER JOIN table2 t2 ...
INNER JOIN table3 t3 ...

Wie mache ich dasselbe in SQL Server?

95
Byron Whitlock

In diesem Beispiel können Sie die "gelöschte" Pseudo-Tabelle nutzen. So etwas wie:

begin transaction;

   declare @deletedIds table ( id int );

   delete t1
   output deleted.id into @deletedIds
   from table1 t1
    join table2 t2
      on t2.id = t1.id
    join table3 t3
      on t3.id = t2.id;

   delete t2
   from table2 t2
    join @deletedIds d
      on d.id = t2.id;

   delete t3
   from table3 t3 ...

commit transaction;

Natürlich können Sie eine "Ausgabe gelöscht" ausführen. Beim zweiten Löschen auch, wenn Sie etwas für die dritte Tabelle benötigen.

Als Randnotiz können Sie auch. * In eine insert-Anweisung einfügen und sowohl. * Als auch gelöscht. * In eine update-Anweisung einfügen.

EDIT: Haben Sie auch erwogen, einen Trigger für table1 hinzuzufügen, um ihn aus table2 + 3 zu löschen? Sie befinden sich in einer impliziten Transaktion und haben auch die Pseudotabellen "insert ." und "delete." Zur Verfügung.

104
John Gibb
  1. Sie können immer kaskadierende Löschungen für die Beziehungen der Tabellen einrichten.

  2. Sie können die mehreren Löschungen in einer gespeicherten Prozedur kapseln.

  3. Sie können eine Transaktion verwenden, um eine Arbeitseinheit sicherzustellen.

15
Aaron Daniels

Sie können die JOIN-Syntax in FROM-Klausel in DELETE in SQL Server verwenden. Sie löschen jedoch immer nur aus der ersten Tabelle und der proprietären Transact-SQL-Erweiterung, die eine Alternative zur Unterabfrage darstellt. 

Aus Beispiel hier :

 -- Transact-SQL extension
 DELETE 
   FROM Sales.SalesPersonQuotaHistory 
     FROM Sales.SalesPersonQuotaHistory AS spqh INNER JOIN 
          Sales.SalesPerson AS sp ON spqh.BusinessEntityID = sp.BusinessEntityID
    WHERE sp.SalesYTD > 2500000.00;
14
topchef

Beispiel für das Löschen einiger Datensätze aus der Mastertabelle und der entsprechenden Datensätze aus zwei Detailtabellen:

BEGIN TRAN

  -- create temporary table for deleted IDs
  CREATE TABLE #DeleteIds (
    Id INT NOT NULL PRIMARY KEY
  )

  -- save IDs of master table records (you want to delete) to temporary table    
  INSERT INTO #DeleteIds(Id)
  SELECT DISTINCT mt.MasterTableId
  FROM MasterTable mt 
  INNER JOIN ... 
  WHERE ...  

  -- delete from first detail table using join syntax
  DELETE d
  FROM DetailTable_1 D
  INNER JOIN #DeleteIds X
    ON D.MasterTableId = X.Id


  -- delete from second detail table using IN clause  
  DELETE FROM DetailTable_2
  WHERE MasterTableId IN (
    SELECT X.Id
    FROM #DeleteIds X
  )


  -- and finally delete from master table
  DELETE d
  FROM MasterTable D
  INNER JOIN #DeleteIds X
    ON D.MasterTableId = X.Id

  -- do not forget to drop the temp table
  DROP TABLE #DeleteIds

COMMIT
11
Pavel Hodek

Ich frage mich nur ... ist das in MySQL wirklich möglich? es wird t1 und t2 löschen? oder ich habe die Frage einfach falsch verstanden.

Wenn Sie jedoch einfach table1 mit mehreren Join-Bedingungen löschen möchten, geben Sie der Tabelle, die Sie löschen möchten, keinen Alias ​​an

diese:

DELETE t1,t2 
FROM table1 AS t1 
INNER JOIN table2 t2 ...
INNER JOIN table3 t3 ...

sollte so geschrieben sein, um in MSSQL zu funktionieren:

DELETE table1
FROM table1 
INNER JOIN table2 t2 ...
INNER JOIN table3 t3 ...

um zu sehen, wie die beiden anderen gängigen RDBMS einen Löschvorgang ausführen:

http://mssql-to-postgresql.blogspot.com/2007/12/deleting-duplicates-in-postgresql-ms.html

9
Michael Buen

Grundsätzlich müssen Sie in einer Transaktion drei Löschaussagen machen, zuerst die Kinder und dann die Eltern. Das Einrichten von kaskadierten Löschvorgängen ist eine gute Idee, wenn dies keine einmalige Angelegenheit ist und deren Existenz nicht mit einem vorhandenen Trigger-Setup in Konflikt steht.

7
Yishai

In SQL Server gibt es keine Möglichkeit, mehrere Tabellen mithilfe von join ..__ zu löschen. Sie müssen also zuerst vom untergeordneten Element löschen, bevor Sie das übergeordnete Formular löschen.

3
tiny

Dies ist eine alternative Methode zum Löschen von Datensätzen, ohne Waisen zu verlassen.

 Deklaration von @user Tabelle (keyValue int, someString varchar (10)) 
 Einfügen in @user 
 Werte (1, '1 Wert') 

 Einfügen in @user
 Werte (2, '2 Wert') 

 Einfügen in @user 
 Werte (3, '3 Wert') 

 Deklarieren Sie @password Table (keyValue int, details varchar ( 10)) 
 Einfügen in @password 
 Werte (1, '1 Passwort') 
 Einfügen in @password 
 Werte (2, '2 Passwort') 
 Einfügen in @password 
 Werte (3, '3 Passwort') 

 --vor dem Löschen 
 Wählen Sie * aus @Kennwort aus. a innerer Join @user b 
 auf a.keyvalue = b.keyvalue 
 select * in #deletedID von @user, wobei keyvalue = 1 - dies funktioniert wie das Ausgabebeispiel 
 lösche @user Dabei ist keyvalue = 1 
 Lösche @Kennwort, bei dem der Schlüsselwert eingegeben wird (Schlüsselwert aus #deletedid auswählen) 

 --Nach dem Löschen --
 Wählen Sie * aus @Kennwort aus. a innerer Join @user b 
 auf a.keyvalue = b.keyvalue 

2
hidden

Alles wurde darauf hingewiesen. Verwenden Sie einfach entweder DELETE ON CASCADE für die übergeordnete table oder löschen Sie vom child-table zur parent.

2
kayode

Wie bereits erwähnt, können Sie das Löschverhalten auf CASCADE setzen. Dies löscht untergeordnete Datensätze, wenn ein übergeordneter Datensatz gelöscht wird. Wenn Sie keine andere Magie wünschen (in diesem Fall wären die Punkte 2, 3 von Aarons Antwort nützlich), sehe ich nicht, warum Sie mit inneren Verknüpfungen löschen müssen.

1
Peter Perháč

Um auf John Gibbs Antwort aufzubauen, zum Löschen eines Datensatzes in zwei Tabellen mit einer FK-Beziehung:

--*** To delete from tblMain which JOINs to (has a FK of) tblReferredTo's PK  
--       i.e.  ON tblMain.Refer_FK = tblReferredTo.ID
--*** !!! If you're CERTAIN that no other rows anywhere also refer to the 
--      specific rows in tblReferredTo !!!
BEGIN TRAN;

    --*** Keep the ID's from tblReferredTo when we DELETE from tblMain
    DECLARE @tblDeletedRefs TABLE ( ID INT );
    --*** DELETE from the referring table first
    DELETE FROM tblMain 
    OUTPUT DELETED.Refer_FK INTO @tblDeletedRefs  -- doesn't matter that this isn't DISTINCT, the following DELETE still works.
    WHERE ..... -- be careful if filtering, what if other rows 
                --   in tblMain (or elsewhere) also point to the tblReferredTo rows?

    --*** Now we can remove the referred to rows, even though tblMain no longer refers to them.
    DELETE tblReferredTo
    FROM   tblReferredTo INNER JOIN @tblDeletedRefs Removed  
            ON tblReferredTo.ID = Removed.ID;

COMMIT TRAN;
0
AjV Jsy