使用触发器防止在单行上删除

Posted

技术标签:

【中文标题】使用触发器防止在单行上删除【英文标题】:Prevent delete on single row with trigger 【发布时间】:2015-01-16 21:44:06 【问题描述】:

我有这张桌子:

CREATE TABLE Workspaces (
AreaNr CHAR(2)
    CONSTRAINT ck_a_areanr REFERENCES Areas(AreaNr)
    ON DELETE CASCADE
    ON UPDATE NO ACTION,
SpaceNr INT
    CONSTRAINT ck_spacenr CHECK (SpaceNr > 0 AND SpaceNr < 1001),
Area DECIMAL(2,1)
    CONSTRAINT ck_areal CHECK (area > 0),
CONSTRAINT ck_workspaces PRIMARY KEY (AreaNr, SpaceNr)
)

现在我想创建一个触发器,以防止从表 Workspaces 中删除单行(随机选择)。目前我有以下触发器,但这个触发器仍然允许删除单行。

当前触发器:

CREATE TRIGGER deleteWorkspace ON Workspaces
FOR DELETE AS

BEGIN
DECLARE @Count int
SET @Count = @@ROWCOUNT;

IF @Count >= (SELECT SUM(row_count)
FROM sys.dm_db_partition_stats
WHERE OBJECT_ID = OBJECT_ID('Workspaces') AND index_id = 1
)

BEGIN
RAISERROR('You cannot delete all rows from Workspaces!',16,1)
ROLLBACK TRANSACTION
RETURN;
END

END
GO

期望的结果:我希望能够防止删除上表中的单行,如果有人可以帮助我更改上面的触发器以便修复此问题,我将非常感激。有谁知道如何做到这一点?

【问题讨论】:

【参考方案1】:

您将希望在此实例中使用已删除的虚拟表。我不完全确定您为什么只关心 single 行删除,但这里是代码:

CREATE TRIGGER deleteWorkspace ON Workspaces
FOR DELETE AS

IF(SELECT COUNT(*) FROM deleted) = 1
BEGIN
RAISERROR('Single Delete Not Allowed!', 16, 1)
ROLLBACK
END
ELSE
RAISERROR('Multiple Rows Being Deleted, Allowed!', 16, 1)
BEGIN
END

END
GO

-肖恩

【讨论】:

由于某种原因,我不得不使用以下格式来交换 RAISEERROR (SQL 2012) THROW 51000, 'Delete not Allowed.', 1;

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

将单行及其标题转换为两列[重复]

Oracle 中的删除分区触发器

防止在 Oracle 中删除某些行

从输入中删除字符时,如何防止 keyup 事件触发两次?

在高并发写入表上使用触发器防止死​​锁错误

Knockout JS 防止在特定子节点上触发点击事件