Question

Good evening.

I had a task to create a trigger which will compare records inserted by

insert into tbl(row1, row2) 
values('val1', 'val2')

So I wrote:

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

Trigger itself creates. But it doesn't work properly. It gives messages:

Adres juz istnieje
Msg 50000, Level 1, State 2
Msg 3609, Level 16, State 1, Line 1
The transaction ended in the trigger. The batch has been aborted.

And what is most important, it gives the errors, when i DON'T DUPLICATE ANY OF COLUMNS AT ALL. It deny try of inserting ANY record to the table "miejsce"

Insert command I used:

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

Solution

You have created an AFTER Trigger which fire when the changes has been made to the database. you need to create an Instead of trigger so you can roll back any invalid operations before it is committed to the disk.

Something like this......

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

If you want to raise error , error severity level must be above 10 because any error under severity level 11 are considered as warring messages not error.

OTHER TIPS

The newly inserted row is already in the table when check is made inside the trigger. Here's a simplified sample to demonstrate it:

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

If you have a proper primery key, use it in the where clause.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top