2016-08-13 4 views
-1

@ accid2が@accidと等しくない場合、比較を実行したい場合は、アクションをロールバックし、そうでない場合はinsertを実行します。else expressionがうまく動作しない場合

このトリガーの結果は、一致していなくても、私のテーブルに挿入されます。ここ

は私のコードです:

ALTER TRIGGER [dbo].[TG_checkacctypehtl] 
ON [dbo].[Accommodation_Hotel] INSTEAD OF INSERT 
AS 
DECLARE @accid NVARCHAR(50), @accid2 NVARCHAR(50),@hid NVARCHAR(50),@fsp NVARCHAR(50), @fc NVARCHAR(50), @sr NVARCHAR(50); 
SELECT @hid = i.hotel_id FROM INSERTED i; 
SELECT @fsp = i.facillities_swimming_pool FROM INSERTED i; 
SELECT @fc = i.facillities_catering FROM INSERTED i; 
SELECT @sr = i.star_rating FROM INSERTED i; 
SELECT @accid2 = i.accommodation_id FROM INSERTED i; 
SELECT @accid = accommodation_id FROM [dbo].[Accommodation] WHERE accommodation_type= 'hotel' AND [email protected]; 
BEGIN 
BEGIN TRAN 
SET NOCOUNT ON 
PRINT @accid2 
PRINT @accid 
IF(@accid2 != @accid) 
BEGIN 
RAISERROR('Record Not Inserted, Accommodation ID is not a Hotel Id',16,1); ROLLBACK; END 
ElSE BEGIN 
INSERT INTO [dbo].[accommodation_hotel] (hotel_id,facillities_swimming_pool,facillities_catering,star_rating,accommodation_id) 
     VALUES (@hid,@fsp,@fc,@sr,@accid2);COMMIT; 

END 
END 

*プリントは、チェックのために私が取得値です。

私のロジックエラーまたは私の構文エラーですか?

+0

以外にも、トリガー内でコミットまたはロールバックを実行することは一般的には悪い考えです。 – sstan

+0

'@ accid2'と' @ accid'の値は何ですか? – sstan

+0

あなたのトリガーには**メジャー**の欠陥があります。**行ごとに一度**呼び出されると仮定しているように思われます。**これは**ケースではありません。トリガは**文ごとに** **起動します。したがって、このトリガを起動させる 'INSERT'文が25行挿入された場合、トリガは一度**発生しますが、' Inserted'擬似テーブルは25行あります。あなたのコードがここで選択する25行のうちどれですか? 'SELECT @id = u.id FROM Inserted u' - これは非決定論的なもので、**任意の行**を取得し、**すべての行を無視します**。これを考慮に入れてトリガーを書き直す必要があります。 –

答えて

-1

は、私はこのような全体のトリガーに何かを書き換えるでしょう

+0

を試してみてください。同じですが、accidとaccid2が等しくない場合でもテーブルに挿入されます。 –

+0

'!='は '<>'と同じです – sstan

+1

悪いです。 <>、決して知らなかったように学んだ!=有効だった。それは誤りだと思った。多くの人と同様に、私は複数の言語を扱い、それが悲しいものだと思った。 – Aeroradish

1

(@accid @ accid2 <>)のIF ...

ALTER TRIGGER [dbo].[TG_checkacctypehtl] 
ON [dbo].[Accommodation_Hotel] 
INSTEAD OF INSERT 
AS 
BEGIN 
    SET NOCOUNT ON; 
INSERT INTO [dbo].[accommodation_hotel] (hotel_id,facillities_swimming_pool,facillities_catering,star_rating,accommodation_id) 
SELECT i.hotel_id 
     ,i.facillities_swimming_pool 
     ,i.facillities_catering 
     ,i.star_rating 
     ,i.accommodation_id 
FROM inserted i 
WHERE EXISTS (SELECT 1 
       FROM [dbo].[Accommodation] a 
       WHERE a.accommodation_type= 'hotel' 
       AND a.accommodation_id = i.accommodation_id) 

IF EXISTS (SELECT 1 FROM inserted i 
      WHERE NOT EXISTS (SELECT 1 
           FROM [dbo].[Accommodation] a 
           WHERE a.accommodation_type= 'hotel' 
           AND a.accommodation_id = i.accommodation_id) 
      ) 
    BEGIN 
    RAISERROR('Records with invalid Accommodation ID is not a Hotel Id not inserted',16,1); 
    END 
END 

が有効宿泊IDを持つ行を挿入した場合にエラーを発生させることべき無効なホテルIDを持つ行があります。これらの変数もすべて必要ありません。

また、トランザクションごとにトリガーされ、各行でトリガーされません。あなたのコードでは、一度に1つの行だけがテーブルに挿入されると仮定しています。

+0

私は "1"と "a"が何のために使われているのか知っていますか? –

+0

'1'は' EXISTS'演算子の単なる値で、 '1'は何でもかまいませんし、' * 'や' NULL'でも正しく動作します。 'a'は' [dbo]。[Accommodation] 'テーブルの別名です。 –

関連する問題