복붙노트

[SQL] 동일한 SQL 문에 여러 테이블에서 삭제할 수 있습니까?

SQL

동일한 SQL 문에 여러 테이블에서 삭제할 수 있습니까?

그것은 다음과 같은, 삭제할 설정을 한정 문을 조인을 사용하여 삭제할 수있다 :

DELETE J
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')

그러나 나는이 기준을 조인의 양쪽을 삭제에 관심이 있어요 - LinkingTable 기록하고 의존하는 사용자 기록을 모두. 나는 내 솔루션 먼저 엔티티 프레임 워크 코드이기 때문에 폭포를 켤 수 없습니다 및 양방향 관계는 여러 캐스케이드 경로에 대한합니다.

이상적으로, 내가 좋아하는 뭔가 싶습니다

DELETE J, U
FROM Users U
inner join LinkingTable J on U.id = J.U_id
...

구문이 작동하지 않습니다,하지만 난 이런 일이 가능한지 궁금 하군요?

해결법

  1. ==============================

    1.아니, 당신은 여러 개의 문을 실행해야 할 것입니다.

    아니, 당신은 여러 개의 문을 실행해야 할 것입니다.

    두 테이블에서 삭제해야하기 때문에, 일치하는 ID의 임시 테이블을 만드는 것이 좋습니다 :

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

    그리고 각 테이블에서 삭제 :

    DELETE FROM Users 
    WHERE Id IN (SELECT Id FROM #RecordsToDelete)
    
    DELETE FROM LinkingTable
    WHERE Id IN (SELECT Id FROM #RecordsToDelete)
    
  2. ==============================

    2.당신이 말하는 방법은 SQL Server에 대한 MY SQL에서 가능하지만

    당신이 말하는 방법은 SQL Server에 대한 MY SQL에서 가능하지만

    당신은 같은 시간에 두 테이블에서 값을 삭제하는 "삭제"의사 테이블로 사용할 수 있습니다

     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;
    

    간단한 설명을 위해이 링크 좀 걸릴 수 있습니다

    및 삭제 된 테이블의 사용을 알고 당신은 삽입과 삭제 된 테이블을 사용하여이 작업을 수행 할 수 있습니다

  3. ==============================

    3.내가 생각할 수있는 유일한 방법은 절차 적 방법으로 양방향 외래 키 휴식 논리적이다.

    내가 생각할 수있는 유일한 방법은 절차 적 방법으로 양방향 외래 키 휴식 논리적이다.

    당신이 시각화 상태 또는 상태에 대한 몇 가지 플래그가없는 경우이 방법은 응용 프로그램 측에 큰 영향을 미칠 수 있습니다

    같은 뭔가

    그런 다음 SQL과 같을 것이다

    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
    

    각 트랜잭션은 양방향 키 당 최소 4 개 DML 작업이 될 것이기 때문에이 방법은 성능에 영향을 미칠 것입니다.

  4. ==============================

    4.거래에 사용 TRY의 CATCH

    거래에 사용 TRY의 CATCH

    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
    

    또는 당신은 또한 같은위한 저장 프로 시저를 사용할 수 있습니다 트랜잭션으로 저장 프로 시저를 사용하여 :

  5. ==============================

    5.당신이 T-SQL을 통해 외부 키를 작성하는 경우에는 외래 키에 ON DELETE CASCADE 옵션을 추가해야합니다 :

    당신이 T-SQL을 통해 외부 키를 작성하는 경우에는 외래 키에 ON DELETE CASCADE 옵션을 추가해야합니다 :

    Code Snippet 
    
    ALTER TABLE <tablename>
    ADD CONSTRAINT <constraintname> FOREIGN KEY (<columnname(s)>)
    REFERENCES <referencedtablename> (<columnname(s)>)
    
    ON DELETE CASCADE;
    
  6. from https://stackoverflow.com/questions/17539145/is-it-possible-to-delete-from-multiple-tables-in-the-same-sql-statement by cc-by-sa and MIT license