0

私はそのようなトリガーを持っています-そのような名前の機器(常に1つの要素)がすでにテーブルにあるときにロールバックする必要があります。ただし、トリガーは常にメッセージを使用してトランザクションをロールバックします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 OFUNIQUEただし、名前列に制約を定義する方がはるかに簡単です。

また、挿入トリガーがテーブル内に複数の行を持つ可能性があることも考慮する必要がありinsertedます。例えば:

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

2行表示されます

これは、さまざまなトリガーの動作を示すです

トリガーを使用してこれを行うにFORは、次のようにします。

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

ただし、複数の同時トランザクションを処理できるかどうかはわかりません。

于 2012-12-16T21:38:48.847 に答える