问题:
在我们的SQL-Server 2005数据库中,我们有一个表T_Groups
除其他外,T_Groups还包括字段ID(PK)和名称。
现在我们公司的一些白痴使用这个名字作为映射表的关键...
这意味着现在可能不会改变组名,因为如果有的话,映射就会消失......
现在,在解决此问题之前,我需要为T_Groups添加限制,因此无法更新组的名称。
请注意,插入仍然是可能的,并且还应该可以进行不更改组名的更新。
另请注意应用程序的用户&开发人员拥有dbo和sysadmin权限,因此REVOKE / DENY将无法正常工作。
如何使用触发器执行此操作?
答案 0 :(得分:11)
CREATE TRIGGER dbo.yournametrigger ON T_Groups
FOR UPDATE
AS
BEGIN
IF UPDATE(name)
BEGIN
ROLLBACK
RAISERROR('Changes column name not allowed', 16, 1);
END
ELSE
BEGIN
--possible update that doesn't change the groupname
END
END
答案 1 :(得分:7)
CREATE TRIGGER tg_name_me
ON tbl_name
INSTEAD OF UPDATE
AS
IF EXISTS (
SELECT *
FROM INSERTED I
JOIN DELETED D ON D.PK = I.PK AND ISNULL(D.name,I.name+'.') <> ISNULL(I.name,D.name+'.')
)
RAISERROR('Changes to the name in table tbl_name are NOT allowed', 16,1);
GO
根据您访问数据库的应用程序框架,检查更改的更便宜方法是Alexander's answer。某些框架将生成包含所有列的SQL更新语句,即使它们没有更改,例如
UPDATE TBL
SET name = 'abc', -- unchanged
col2 = null, -- changed
... etc all columns
UPDATE()
函数仅检查语句中列是 present ,而不是其值是否已更改。此特定语句将使用UPDATE()
引发错误,但如果使用如上所示的更复杂的触发器进行测试则不会。
答案 2 :(得分:0)
这是一个使用更新触发器保留一些原始值的示例。 它的工作原理是每次将 orig_author 和 orig_date 的值设置为已删除伪表中的值。它仍然执行工作并使用循环。
CREATE TRIGGER [dbo].[tru_my_table] ON [dbo].[be_my_table]
AFTER UPDATE
AS
UPDATE [dbo].[be_my_table]
SET
orig_author = deleted.orig_author
orig_date = deleted.orig_date,
last_mod_by = SUSER_SNAME(),
last_mod_dt = getdate()
from deleted
WHERE deleted.my_table_id IN (SELECT DISTINCT my_table_id FROM Inserted)
ALTER TABLE [dbo].[be_my_table] ENABLE TRIGGER [tru_my_table]
GO