当对包含另一个用户已存在的电子邮件地址的记录运行以下查询时,我的应用程序在数据库中的“更新后”触发器上抛出异常。换句话说,记录尚未更新,但由于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
)
)
)
答案 0 :(得分:2)
在sql server中,只要update语句成功完成,就会触发更新后触发器,即使没有实际更新记录。
仅在触发SQL语句后才执行AFTER触发器 已成功执行。
因此,您必须通过比较inserted
和deleted
表之间的数据来检查相关数据是否确实发生了变化。
这是一个简单的例子:
创建样本表并触发:
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