我有这样的触发器 - 它应该在具有这种名称的设备(总是一个元素)已经在表中时回滚。
但触发器始终使用消息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
答案 0 :(得分:2)
定义为FOR
的触发器发生在导致它的SQL之后。因此,从您的事务的角度来看,该行已经在表中。如果您想通过触发器执行此操作,则需要使用INSTEAD OF
。但是,在名称列上定义UNIQUE
约束要容易得多。
您还应该考虑插入触发器在inserted
表中可以有多行。例如:
Insert Into TEquipment (Name) Values (N'Test'), (N'Test');
会显示两行
这里显示了an example不同的触发器行为
要使用FOR
触发器执行此操作,您可以执行以下操作:
http://sqlfiddle.com/#!6/7d51d/1
尽管如此,我不确定它会处理多个并发事务。