我希望在更改时触发对特定列的更新。
(历史:一些应用程序对列进行更新,但我找不到哪个应用程序。因此,我决定创建一个触发器来强制返回值)。
为了简单起见..
UsrTbl:
usrid usr   pwd
1001  admin qwerty
2001  cto   demo
3001  ceo   demo
...如果有人在pwd上进行了更新,其中usr是admin,我希望将其重新更新为特定值。
如果我使用触发器,就像这样:
CREATE TRIGGER the_usr_trg ON usrtbl AFTER UPDATE AS
UPDATE usrtbl SET pwd='qwerty' WHERE usr = 'admin'
GO上面能帮我解决这个问题吗?当触发器更新列时会发生什么?它会再次触发the_usr_trg触发器吗?这会在数据库服务器中导致循环吗?或者它只会运行一次?有没有更好的方法来解决这个问题?(除了查找本专栏正在更新的应用程序之外:)
谢谢!
发布于 2012-02-21 22:56:11
我相信这将取决于DB上触发器的递归级别。如果RECURSIVE_TRIGGERS设置为OFF,那么它将只运行一次。在您的示例中,如果创建一个INSTEAD OF触发器会更好,从而避免表上的第一个UPDATE。在您的例子中,应该是这样的:
CREATE TRIGGER the_usr_trg ON usrtbl 
INSTEAD OF UPDATE 
AS
BEGIN
    UPDATE A
    SET pwd= B.pwd
    FROM usrtbl A
    INNER JOIN INSERTED B
        ON A.usr = B.usr
    WHERE usr != 'admin'
END发布于 2012-02-21 22:57:56
默认情况下,触发器不会以递归方式调用自身,除非您使用以下语句告诉它们:
SET RECURSIVE_TRIGGERS ON您的代码应该工作得很好。
发布于 2012-02-21 23:11:37
根据@cadrell0的评论,您可以只在开发环境中测试它,看看它是否会递归。
一个更大的问题是,您只是通过重置值来掩盖裂缝,而不是找出根本原因-查看诸如系统视图sys.trigger_events或实现审计表(这是使用触发器的一种更典型的方式)之类的内容,以了解值何时以及为什么发生更改。
忽略了这样一个事实,即以纯文本存储密码是非常糟糕的…
为了避免触发器中的递归,您可以使用插入的表来查看所建议的更改,或者使用触发器update()函数来查看列是否已经更改。如果该列已经设置为所需的值,则无需再次更新它。
https://stackoverflow.com/questions/9379164
复制相似问题