lapots
lapots

Reputation: 13395

trigger always rollback transaction

I've got such trigger - it should rollback when the equipment(always one element) with such name is already in the table. But trigger always rollback transaction with message such equipment already exist. When equipment is in the table and when isn't. What is the problem?

CREATE trigger [dbo].[ut_TEquipment]
on [dbo].[TEquipment]
for insert
as
begin

declare @var nvarchar(30)
select @var = name from inserted
print @var

if (@var in (select name from TEquipment))
begin
    raiserror('Such equipment already exist',10,1)
    rollback transaction
end

declare @amount int
declare @free int

 select @amount = x.amount from inserted as x 

 select @free = y.free from TEquipWarehouse as y,inserted as x
 where y.ideqwhs = x.ideqwhs

if (@free - @amount) <= 0
begin
raiserror('Free space in this warehouse is not enough!',10,1)
rollback transaction
end
else 
begin
update TEquipWarehouse
set free = capacity - amount
from inserted as x
    where idwhstype = x.ideqwhs 
end

end

Upvotes: 0

Views: 2132

Answers (1)

Laurence
Laurence

Reputation: 10976

A trigger defined as FOR happens after the SQL that causes it. So from your transaction's point of view, the row is already in the table. If you want to do this through triggers, you'll need to use INSTEAD OF. However, it would be a lot easier to define a UNIQUE constraint on the name column.

You should also consider that an insert trigger can have multiple rows in the inserted table. For example:

Insert Into TEquipment (Name) Values (N'Test'), (N'Test');

would show two rows

Here's an example showing the different trigger behavoiurs

To do this using FOR triggers you'd do something like this:

http://sqlfiddle.com/#!6/7d51d/1

Though, I'm not sure it would deal with multiple concurrent transactions.

Upvotes: 2

Related Questions