2016-02-03 43 views
2

我想寫我的第一個觸發器。我有元素表。我裏面有很少的記錄。很少有記錄在1上的複選框,在0上很少。簡單觸發初學者防止刪除

我試圖做出觸發器,以防止刪除記錄上有複選框1(elm_intcolumn1)。

觸發器正在工作,但我無法用複選框0刪除記錄。觸發器阻止了我的元素上的所有記錄。

ALTER TRIGGER [dbo].[test] 
    ON [dbo].[elements] 
    INSTEAD OF DELETE 
AS 
BEGIN 
    SELECT CASE 
     WHEN elm_intcolumn1 = 1 
      THEN 0 
     WHEN elm_intcolumn1 = 0 
      THEN 1 
    END 
    FROM elements 
    BEGIN 
     RAISERROR ('błąd', 16, 1) 
     ROLLBACK TRANSACTION 
     RETURN; 
    END 
END 
+0

觸發火災每一次*語句*,不是每一次行* *。如果有人寫了一個刪除(至少)一行'elm_intcolumn1'爲1的行,並且(至少)一行刪除了0行,那麼你希望發生什麼? –

回答

0

您的解決方案過於複雜。

首先 - 您不需要檢查創建哪個觸發器的表格,而是檢查instead of delete觸發器的上下文中名爲deleted的特殊表格。此表格包含您正試圖刪除的記錄。

第二 - 您的支票應該只是「有刪除表中有」elm_intcolumn1 = 1「的記錄」。如果是 - 然後拋出異常,如果沒有這樣的記錄 - 然後從表中刪除deleted的所有記錄。在這種情況下,你的表應該有一些主鍵(我假設它在下面的示例中命名爲ID)。

所以從字面上是這樣的:

if exists(select * from deleted where elm_intcolumn1 = 1) 
begin 
    RAISERROR ('błąd', 16, 1) 
    ROLLBACK TRANSACTION 
    RETURN; 
end 
else 
begin 
    delete from elements where ID in (select ID from deleted) 
end 

通知你必須明確地從表中該觸發器刪除記錄,因爲它是instead of delete,不after delete

或者,您可以將觸發器類型更改爲after delete,因此不需要在else條件分支中進行顯式刪除。

1

檢查有關虛擬表DELETEDINSERTED -

CREATE TABLE dbo.[elements] (
    id INT IDENTITY PRIMARY KEY, 
    elm_intcolumn1 BIT 
) 
GO 
INSERT INTO dbo.[elements] (elm_intcolumn1) 
VALUES (0), (1) 
GO 

ALTER TRIGGER dbo.test 
    ON dbo.[elements] 
    AFTER DELETE 
AS 
BEGIN 
    IF EXISTS(
     SELECT 1 
     FROM DELETED 
     WHERE elm_intcolumn1 = 1 
    ) 
    BEGIN 
     RAISERROR ('revert', 16, 1) 
     ROLLBACK TRANSACTION 
    END 
END 
GO 

SELECT * FROM dbo.[elements] 

DELETE dbo.[elements] 
WHERE id = 2 

當刪除第二個記錄:

Msg 50000, Level 16, State 1, Procedure test, Line 39 
revert 
Msg 3609, Level 16, State 1, Line 29 
The transaction ended in the trigger. The batch has been aborted. 
+0

但是,當我刪除有複選框0的記錄時,他不是從元素中刪除。我只想阻止刪除具有複選框1的元素。 – Michal

+0

@Michal請檢查更新 – Devart

+0

非常感謝你現在它正在工作,它是多麼清楚我是如何工作觸發:) – Michal