SQL:重复触发器msg 3609

时间:2014-05-05 20:46:20

标签: sql sql-server triggers duplicates

晚上好。

我有一个创建触发器的任务,该触发器将比较

插入的记录
insert into tbl(row1, row2) 
values('val1', 'val2')

所以我写道:

CREATE TRIGGER duplikat_miejsce ON miejsce
AFTER INSERT
AS
if exists ( select * from miejsce i 
    inner join inserted t on i.ulica=t.ulica and i.numer=t.numer and i.miasto=t.miasto and i.kod=t.kod)
begin
    RAISERROR ('Adres juz istnieje',1,2)
    rollback
end
go

触发器本身创建。但它没有正常工作。它给出了消息:

  

Adres juz istnieje
  消息50000,级别1,状态2
  消息3609,级别16,状态1,行1   交易在触发器中结束。批次已中止。

最重要的是,它给出了错误,当我完全没有任何栏目时。它拒绝尝试将任何记录插入表格" miejsce"

我使用的插入命令:

insert into miejsce(id_miejsce, ulica, numer, miasto, kod, telefon, uwagi) 
values (6, 'Widmowa', '14', 'Warszawka', '88-800', null, null)

2 个答案:

答案 0 :(得分:0)

在触发器内进行检查时,新插入的行已经在表中。这是一个简化的示例来演示它:

create table t (i int, j int);
go
insert t values (1,1);
go

create trigger tr
on t
after insert
as
select * from t;
if exists(select * from t inner join inserted i on t.i = i.i and t.j = i.j)
begin
    raiserror ('Adres juz istnieje',1,2);
    rollback;
end
go

insert t values(2,2)
go

drop table t
go

如果你有一个合适的素数键,请在where子句中使用它。

答案 1 :(得分:0)

您创建了一个AFTER触发器,当对数据库进行了更改时触发。您需要创建一个而不是触发器,以便在将任何无效操作提交到磁盘之前回滚它们。

像这样......

CREATE TRIGGER duplikat_miejsce ON miejsce
INSTEAD OF INSERT
AS
BEGIN
IF EXISTS (select * from miejsce i 
           inner join inserted t 
           on i.ulica   = t.ulica 
           and i.numer  = t.numer 
           and i.miasto = t.miasto 
           and i.kod    = t.kod)
  BEGIN
    RAISERROR ('Adres juz istnieje',16,1)
  END
ELSE 
  BEGIN

   INSERT INTO miejsce (id_miejsce, ulica, numer, miasto, kod, telefon, uwagi)
   SELECT t.id_miejsce, t.ulica, t.numer, t.miasto, t.kod, t.telefon, t.uwagi
   FROM inserted t
   WHERE NOT EXISTS (select 1 
                     from miejsce i 
                     WHERE i.ulica   = t.ulica 
                     and i.numer  = t.numer 
                     and i.miasto = t.miasto 
                     and i.kod    = t.kod)
  END


END

如果要引发错误,则错误严重性级别必须高于10,因为严重级别11下的任何错误都被视为交战邮件而非错误。