Is it possible to delete from multiple tables in the same SQL statement?

后端 未结 5 1478
自闭症患者
自闭症患者 2020-11-27 07:10

It\'s possible to delete using join statements to qualify the set to be deleted, such as the following:

DELETE J
FROM Users U
inner join LinkingTable J on U.         


        
相关标签:
5条回答
  • 2020-11-27 07:36

    If you are creating the foreign key through T-SQL you must append the ON DELETE CASCADE option to the foreign key:

    Code Snippet 
    
    ALTER TABLE <tablename>
    ADD CONSTRAINT <constraintname> FOREIGN KEY (<columnname(s)>)
    REFERENCES <referencedtablename> (<columnname(s)>)
    
    ON DELETE CASCADE;
    
    0 讨论(0)
  • 2020-11-27 07:41

    Nope, you'd need to run multiple statements.

    Because you need to delete from two tables, consider creating a temp table of the matching ids:

    SELECT U.Id INTO #RecordsToDelete
    FROM Users U
       JOIN LinkingTable J ON U.Id = J.U_Id
    ...
    

    And then delete from each of the tables:

    DELETE FROM Users 
    WHERE Id IN (SELECT Id FROM #RecordsToDelete)
    
    DELETE FROM LinkingTable
    WHERE Id IN (SELECT Id FROM #RecordsToDelete)
    
    0 讨论(0)
  • 2020-11-27 07:46

    Use TRY CATCH with Transaction

    BEGIN TRANSACTION
    BEGIN TRY
        DELETE from A WHERE id=1
    
        DELETE FROM b WHERE id=1
    
        COMMIT TRANSACTION;
    END TRY
    BEGIN CATCH
    ROLLBACK TRANSACTION;
    END CATCH
    

    or you can also use Store procedure for same Using Stored Procedure With Transaction:

    0 讨论(0)
  • 2020-11-27 07:51

    The way you say is Possible in MY SQL but not for SQL SERVER

    You can use of the "deleted" pseudo table for deleting the values from Two Tables at a time like,

     begin transaction;
    
     declare @deletedIds table ( samcol1 varchar(25) );
    
     delete #temp1
     output deleted.samcol1 into @deletedIds
     from #temp1 t1
     join #temp2 t2
     on t2.samcol1 = t1.samcol1
    
     delete #temp2
     from #temp2 t2
     join @deletedIds d
     on d.samcol1 = t2.samcol1;
    
     commit transaction;
    

    For brief Explanation you can take a look at this Link

    and to Know the Use of Deleted Table you can follow this Using the inserted and deleted Tables

    0 讨论(0)
  • 2020-11-27 07:52

    The only way I could think of is logically break the bi-directional foreign keys in a procedural way.

    This approach can have huge impact to your application side if you don't have some flags for visualization state or status

    Something like

    1. INSERT dummy not visible rows to Users (with something like Id = -1 for dummy values)
    2. Add to LinkingTable an alternative column to point back to Users, I'll call it U_ComesFrom

      ALTER TABLE LinkingTagble ADD U_ComesFrom_U_id INT DEFAULT(-1)

    3. Add FOREIGN KEY with a NOCHECK

      ALTER TABLE LinkingTable WITH NOCHECK
      FOREIGN KEY (U_ComesFrom_U_id)
      REFERENCES Users (Id) ;

    4. Add to Users column

      ALTER TABLE Users ADD MarkedForDeletion BIT NOT NULL DEFAULT(0)

    Then your SQL would look like

    BEGIN TRANSACTION
        UPDATE J
        SET U_Comes_From_U_id = U_ID, U_id = -1 -- or some N/R value that you define in Users
        FROM Users U
        inner join LinkingTable J on U.id = J.U_id
        inner join Groups G on J.G_id = G.id
        WHERE G.Name = 'Whatever'
        and U.Name not in ('Exclude list')
    
        UPDATE U
        SET MarkedForDeletion = 1
        FROM Users
        inner join LinkingTable J on U.id = J.U_ComesFrom_U_id 
        WHERE U_id > 0
    
        DELETE FROM LinkingTable 
        WHERE U_ComesFrom_U_id > 0
    
        DELETE FROM Users
        WHERE MarkedForDeletion = 1
    
    COMMIT
    

    This approach would impact the performance since each transaction would be at least 4 DML operations per bi-directional keys.

    0 讨论(0)
提交回复
热议问题