Sql 虽然删除了所有数据,但插入后的触发器不起作用

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;

我的表是空的,我正在尝试插入一条记录,条件是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;

    --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上迭代并一次处理一行,但如果可能的话,应该避免这样做。