简单触发器初学者防止删除

Posted

技术标签:

【中文标题】简单触发器初学者防止删除【英文标题】:Simple Trigger Beginner Prevent from delete 【发布时间】:2016-02-03 11:06:09 【问题描述】:

我正在尝试编写我的第一个触发器。我有元素表。我里面的记录很少。很少有记录在 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

【问题讨论】:

每个语句触发一次,而不是每个触发一次。如果有人写了一个DELETE,它(至少)删除了elm_intcolumn1 为1 的一行,并且(至少)删除了为0 的一行,那么你想发生什么? 【参考方案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 的记录时,他并没有从元素中删除。我只想防止删除具有复选框 1 的元素。 非常感谢,现在它正在工作,对我来说更清楚触发器是如何工作的:)【参考方案2】:

您的解决方案过于复杂。

首先 - 您不需要检查创建触发器的表,而是检查 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 条件分支中显式删除。

【讨论】:

以上是关于简单触发器初学者防止删除的主要内容,如果未能解决你的问题,请参考以下文章

小白初学者理解(施密特 开漏 推挽输出)

PHP简单利用token防止表单重复提交

防止表单重复提交

大数据初学者问题汇总之恢复已删除的hive表数据

Oracle-4 - :超级适合初学者的入门级笔记:plsql,基本语法,记录类型,循环,游标,异常处理,存储过程,存储函数,触发器

在触发单击 Extjs 3.4 时重新加载 ComboBox 存储