Sql 虽然删除了所有数据,但插入后的触发器不起作用
我的表是空的,我正在尝试插入一条记录,条件是bit type列不为true,因为对于每个国家,true条件只能为一次。这是我的扳机:Sql 虽然删除了所有数据,但插入后的触发器不起作用,sql,sql-server,tsql,database-trigger,Sql,Sql Server,Tsql,Database Trigger,我的表是空的,我正在尝试插入一条记录,条件是bit type列不为true,因为对于每个国家,true条件只能为一次。这是我的扳机: ALTER TRIGGER [dbo].[Trg_PreventDefaultDevise] ON [dbo].[RELDEVISEPAYS] AFTER INSERT, UPDATE AS BEGIN SET NOCOUNT ON; DECLARE @Pays varchar(2); DECLARE @Compte int = 0;
ALTER TRIGGER [dbo].[Trg_PreventDefaultDevise]
ON [dbo].[RELDEVISEPAYS]
AFTER INSERT, UPDATE
AS
BEGIN
SET NOCOUNT ON;
DECLARE @Pays varchar(2);
DECLARE @Compte int = 0;
--select @Default = Rel_Default from Inserted;
SELECT @Pays = REL_PAYS FROM inserted
PRINT @Pays
SET @Compte = (SELECT COUNT(rel_pays) FROM inserted
WHERE Rel_Pays = @Pays AND Rel_Defaut = 0)
PRINT @compte;
IF (SELECT COUNT(*) FROM RELDEVISEPAYS
WHERE REL_DEFAUT = 1 AND REL_PAYS = @Pays) >= 1
BEGIN
RAISERROR (N'Ce pays dispose déjà d''une devise par défaut', 16, 1)
ROLLBACK
RETURN
END
END
这一行select@Pays=REL_Pays from inserted犯了一个典型的SQL Server触发器错误,即假定插入的psuedo表中只有一行,而实际上可能有很多行
您不需要插入表来执行测试。相反,只需检查真实表中是否存在任何重复项,以及是否存在回滚
我想你想要的是:
alter trigger [dbo].[Trg_PreventDefaultDevise] on [dbo].[RELDEVISEPAYS]
after insert, update
as
begin
set nocount on;
if exists (select 1 from dbo.RELDEVISEPAYS where REL_DEFAUT = 1 group by REL_PAYS having count(*) > 1)
begin
raiserror (N'Ce pays dispose déjà d''une devise par défaut',16,1);
rollback;
end;
end
啊,这是真的,我刚刚测试过,它在上帝的火焰中起作用,非常感谢你Hi Dale,感谢你的帮助,但我想了解为什么我的请求没有起作用。你能给我解释一下吗?正如我在回答的第一行中所说,你将@Pays设置为Inserted中的1个随机值,然后只测试该1个值。事实上,如果Inserted可能有多行,则会忽略其余行。SQL Server触发器始终需要以基于集合的方式编写,以处理Inserted有多行的事实。或者,如果您真的必须这样做,您可以在Inserted上迭代并一次处理一行,但如果可能的话,应该避免这样做。