0

我有一个表,其中一个 AutoIdentity 列作为它的 PK 和一个名为“IdentificationCode”的 nvarchar 列。我想要的只是在插入新行时,它会在表中搜索任何预先存在的 IdentificationCode,如果找到,则回滚事务。

我写了以下触发器:

ALTER trigger [dbo].[Disallow_Duplicate_Ids] 
on [dbo].[tbl1]
for insert
as
if ((select COUNT(*) from dbo.tbl1 e , inserted i where e.IdentificationNo = i.IdentificationNo ) > 0)
begin
RAISERROR('Multiple Ids detected',16,1)
ROLLBACK TRANSACTION
end

但是在插入新行时,即使没有这样的IdentificationCode,它总是会触发回滚。

任何人都可以帮助我吗?

谢谢

4

2 回答 2

3

正如@Qpirate 提到的,您可能应该对列施加某种UNIQUE约束。这可能比使用触发器“更强”,因为有办法禁用它们。
此外,隐式连接语法(逗号分隔FROM子句)被视为 SQL 反模式 - 如果可能,请始终明确声明您的连接。

我怀疑您的错误是因为您的触发器似乎是一个AFTER触发器,并且您检查表中是否有任何(非零)行;换句话说,触发器(可能)“失败”了,INSERT 因为它被INSERT编辑了。将其更改为BEFORE(或INSTEAD OF)触发器,或将计数更改为>= 2可以解决问题。

如果没有看到您的插入语句,就不可能确定,但​​是(特别是如果您使用的是 SP),您可以检查INSERT语句本身是否存在,如果未插入行。
例如,以下内容:

INSERT INTO tbl1 (identificationCode, *otherColumns*)
VALUES (@identificationCode, *otherColumns)
WHERE NOT EXISTS (SELECT '1'
                  FROM tbl1
                  WHERE identificationCode = @identificationCode)

SQLCODE = 100如果identificationCode已经存在,将返回一个指示“未找到行”的代码(插入等;在几乎每个系统上都是这样)。

于 2012-07-05T15:51:56.087 回答
0

使用 EXISTS 检查 IdentificationCode 是否已经存在。

If EXISTS (Select * from tbl1 where IdentificationCode = @IdentificationCode )
BEGIN
//do something
END
Else
BEGIN
//do something
END
于 2012-07-05T15:35:20.293 回答