2015-11-01 127 views
0

我有一個像table1table1_id, col1, some_ID),一張桌子和另一table2table2_id, col1, table1_idSQL Server進行刪除觸發器刪除其他表中的記錄與程序

我有一個過程

PROC deleteTable2(@id int) 
AS 
BEGIN 
    DELETE table2 
    WHERE table1_id = @id 
END 

我m試圖爲table1表創建刪除觸發器,所以當我試圖從table1刪除時,觸發器將刪除table2中的所有記錄。

我寫了這樣觸發:

CREATE TRIGGER deleteTable1 on table1 
FOR DELETE 
AS 
BEGIN 
    SET NOCOUNT ON 

    DECLARE @id int = 0 

    SELECT @id = del.table1_ID from deleted as del 

    EXECUTE dbo.deleteTable2 @id 

它的工作原理如果有一個some_ID只有一條記錄,但是如果有更多的記錄,這是行不通的。例如:

delete table1 
where some_ID='some value' 

此SQL查詢將刪除table1中的所有記錄,並且僅刪除table2中的所有記錄。

這是有道理的,所以我做了CURSOR觸發,像

CREATE TRIGGER deleteTable1 ON table1 
FOR DELETE 
AS 
BEGIN 
    DECLARE @id int = 0, @CURSOR cursor 

    SET @CURSOR = CURSOR scroll FOR 
     SELECT deleted.table1_id 
     FROM deleted 

    OPEN @CURSOR 
    FETCH NEXT FROM @CURSOR into @id 

    WHILE @@FETCH_STATUS = 0 
    BEGIN 
      EXECUTE dbo.deleteTable2 @id 
      FETCH NEXT FROM @CURSOR into @id 
    END 
    CLOSE @CURSOR 
END 

但它不工作在所有...也許我只是錯過了一些東西或者我不明白一些細微差別。謝謝。

UPDATE

事實上,這兩個表是在一個分貝,但我有3臺table3 (table3_id, col1, table2_id)。而這table3是在其他數據庫,並通過鏈接的服務器連接。因此,當我嘗試調用存儲過程時,此存儲過程調用存儲過程(使用光標)刪除table3中的記錄。這就是爲什麼我試圖使用存儲過程刪除table2中的記錄的確切原因。

+0

***請*** ......一個觸發器應該**快速,小巧靈活** - 一切都是**光標**絕對不是!請勿在觸發器內使用** CURSOR **(所有內容)來殺死您的系統!這太糟糕了......使用** M.Ali在他的回覆中顯示的** set-based **方法 - **總是**。觸發器內的遊標是任何SQL Server數據庫的**最糟糕的噩夢!從來沒有在任何情況下做到這一點! –

+0

我評論過它。 – bredmann

回答

1

避免使用所有這些不必要的遊標和存儲過程。只需遵循基於集合的方法,並在觸發器內執行以下操作。

CREATE TRIGGER deleteTable1 on table1 
FOR DELETE 
AS 
BEGIN 
SET NOCOUNT ON 

Delete FROM Table2 
WHERE Exists (SELECT 1 
       FROM deleted del 
       WHERE del.table1_ID = table2.Table1_ID)    

END 

UPDATE

既然你已經提到你想從第三表中刪除記錄過這是一個鏈接服務器上的一些地方。

我建議你使用相同的方法,並在鏈接服務器上的第三個表的過程中添加另一個刪除語句。

CREATE TRIGGER deleteTable1 on table1 
FOR DELETE 
AS 
BEGIN 
SET NOCOUNT ON 

Delete FROM Table2 
WHERE Exists (SELECT 1 
       FROM deleted del 
       WHERE del.table1_ID = table2.Table1_ID)    

DELETE FROM t3 
FROM [LinkedServerName].[DBName].[SchemaName].Table3 t3 
WHERE Exists (SELECT 1 
       FROM deleted del 
       WHERE del.table1_ID = t3.Table1_ID)    


END 
+0

@bredmann現在查看答案。 –

+0

table3與table2連接,而不是table1。此外,我很確定觸發器不起作用,因爲「另一個會話使用的事務上下文」問題。因爲我們不能像MS Sql那樣從其他數據庫中刪除。 – bredmann