2016-10-28 63 views
0

我有一個包含一些列的'測試'表。列'已驗證'和'已刪除'是位值在插入多行時在觸發器內回滾一行

TEST Table: 
    Id  VALIDATED  DELETED 
    1   0   0 
    2   0   0 
    3   1   0 
    4   0   0 
    5   1   0 
    6   0   0 

Id是INT值和主鍵。

我已經低於觸發創建該表和列「已刪除」,只有當它被更新:

CREATE TRIGGER [dbo].[MY_TRIGGER] 
    ON [dbo].[TEST] 
    FOR UPDATE 
AS 
IF UPDATE([DELETED]) 
BEGIN 

DECLARE @Id INT; 

DECLARE db_cursor CURSOR FOR 
SELECT DISTINCT (I.Id) 
FROM INSERTED I; 

OPEN db_cursor 
FETCH NEXT FROM db_cursor INTO @Id 

WHILE @@FETCH_STATUS = 0 
BEGIN 

    IF EXISTS(SELECT * FROM INSERTED WHERE Id = @Id AND VALIDATED = 1) 
    BEGIN 

     IF EXISTS (SELECT 
        FROM DELETED D INNER JOIN INSERTED I 
         ON D.Id = I.Id 
        WHERE D.Id = @Id AND D.[DELETED] = 0 
          AND I.[DELETED] = 1) 

     BEGIN 
      RAISERROR('CANNOT DELETE!' ,10, 1); 
      ROLLBACK 
     END 
    END 


    FETCH NEXT FROM db_cursor INTO @Id 
END 

CLOSE  db_cursor; 
DEALLOCATE db_cursor; 
END 

現在我執行以下更新語句:

Update TEST 
SET DELETED=1 

以上觸發避免標記刪除已經驗證的行。 當一行被驗證,我試圖將其標記爲已刪除,然後回滾完成。

我的疑問是: 是否正在更新所有行的Roolback?或者僅針對正在處理的行進行回滾。

我該如何做只回滾提升錯誤和提交其餘的行回滾?

+0

您在上面的觸發器Id,Process_ID和Process中有3個變量。所以,我不確定這個觸發器是否能夠工作。 –

+1

這裏不需要光標。您可以將其作爲一個基於集合的查詢來完成,而完全沒有問題。回滾回滾整個事務,而不是一行。每次操作時,sql server中的觸發器都會觸發一次。 –

+0

@WEI_DBA正確。我已糾正它。打字時發生錯誤。抱歉。 – user1624552

回答

3

擺脫那個遊標。它沒有做任何事情,只是讓它變得比需要的更慢,更復雜。您不需要檢查每一行,只需要查看是否有更新的行違反了您的業務規則。

您的整個觸發器可以簡化爲此。

CREATE TRIGGER [dbo].[MY_TRIGGER] 
    ON [dbo].[TEST] 
    FOR UPDATE 
AS 
    IF EXISTS 
    (
     SELECT * 
     FROM DELETED D 
     INNER JOIN INSERTED I ON D.Id = I.Id 
     WHERE D.[DELETED] = 0 
      AND I.[DELETED] = 1 
    ) 
    BEGIN 
     RAISERROR('CANNOT DELETE!' ,10, 1); 
     ROLLBACK 
    END