【问题标题】:After update Trigger firing, when there's an EXISTS clause to prevent the update更新触发器触发后,当有一个 EXISTS 子句阻止更新时
【发布时间】:2022-04-06 17:30:38
【问题描述】:

当针对包含另一个用户已存在的电子邮件地址的记录运行以下查询时,我的应用程序在数据库中的“更新后”触发器上引发异常。换句话说,该记录尚未更新,但由于 EXISTS 子句本应被忽略。

有人知道它为什么会触发这个事件吗?或者触发器应该测试一些标志以确保它是一个真正的更新?

我在禁用触发器后测试了我的代码,它完全符合预期,所以我假设我的查询是正确的。

电子邮件地址可以为空,否则它在数据库中必须是唯一的。 .

导致这种情况的查询如下。

UPDATE users

SET EmailAddress = @emailaddress

WHERE

(

  RecID = @recid AND fk_Sites_RecID = @fk_sites_recid

  AND

  (

    /* Allow an update when address is being updated with a blank */

    ( @emailaddress = '' )

    /* Address isn't blank, so test it doesn't exist elsewhere */

    OR NOT EXISTS

    (

      SELECT * FROM users

      WHERE

      NOT ( RecID = @recid AND fk_Sites_RecID = @fk_sites_recid )

      AND RTRIM(LTRIM(COALESCE(EmailAddress,''))) = @emailaddress

    )

  )

)

【问题讨论】:

标签: sql sql-server triggers


【解决方案1】:

在 SQL Server 中,只要更新语句成功完成,就会触发更新后触发器,即使实际上没有更新记录

来自CREATE TRIGGER MSDN page

AFTER 触发器仅在触发 SQL 语句之后执行 已成功执行。

因此,您必须通过比较 inserteddeleted 表之间的数据来检查触发器内部是否确实发生了变化。

这是一个简单的例子:

创建示例表和触发器:

CREATE TABLE [dbo].[t] (
    [id] [int] IDENTITY(1,1) NOT NULL PRIMARY KEY,
    [text] [char](1) NOT NULL
);


CREATE TABLE [dbo].[t2](
    [id] [int] NOT NULL,
    [t] [char](1) NOT NULL
);


CREATE TRIGGER [dbo].[t_forupdate]
   ON  [dbo].[t]
   AFTER UPDATE
AS 
BEGIN
    -- SET NOCOUNT ON added to prevent extra result sets from
    -- interfering with SELECT statements.
    SET NOCOUNT ON;

    INSERT INTO t2 
    SELECT id, [text]
    FROM t 

END

插入样本数据:

INSERT INTO T VALUES ('a');

运行不会更改表中任何内容的更新语句

UPDATE T 
SET [text] = 'b'
WHERE 1 = 0;

从示例表中选择:

SELECT *
FROM T2 

SELECT *
FROM T

结果:

t
id          t
----------- ----
1           a


t2
id          text
----------- ----
1           a

【讨论】:

  • 触发器是由我们的承包商生成的,我将您的帖子与错误报告一起转发。他们更正了代码并对其进行了更改,以便他们现在同时使用删除的行和插入的行,而他们最初只是查看插入而不是删除。我不熟悉 sql 函数,但从你所说的来看,它现在看起来好像它们正确地覆盖了它。感谢您的帮助
猜你喜欢
  • 1970-01-01
  • 2018-05-16
  • 2013-09-09
  • 1970-01-01
  • 2016-11-03
  • 2021-03-08
  • 2021-11-05
  • 2016-08-25
  • 2015-01-20
相关资源
最近更新 更多