0

我有这样的触发器 - 当具有这样名称的设备(总是一个元素)已经在表中时,它应该回滚。但触发器总是用 message 回滚事务such equipment already exist。什么时候设备在桌子上,什么时候不在。问题是什么?

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
4

1 回答 1

2

定义为FOR在导致它的 SQL 之后发生的触发器。因此,从您的事务的角度来看,该行已经在表中。如果要通过触发器执行此操作,则需要使用INSTEAD OF. UNIQUE但是,在 name 列上定义约束会容易得多。

inserted您还应该考虑插入触发器在表中可以有多行。例如:

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

将显示两行

这是一个显示不同触发行为的示例

要使用FOR触发器执行此操作,您需要执行以下操作:

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

不过,我不确定它是否会处理多个并发事务。

于 2012-12-16T21:38:48.847 回答