お世話になっております。
SQL Serverのトリガーで質問があります。
★実現したいこと★
SELCT * FROM inserted
のようにinseterdを含んだクエリを変数にいれて実行したいのですが、
オブジェクトが無効と怒られます。
sql
1CREATE TRIGGER [dbo].[trTest] ON [dbo].[テーブルA] 2AFTER UPDATE 3 4/***********トリガー STR ***********/ 5AS 6BEGIN 7 8PRINT '処理を開始します!!!!!' 9 10--行数を返さない 11SET NOCOUNT ON; 12 13--変数宣言 14DECLARE @VarBangou varchar(50) --カーソルの番号を取得 15DECLARE @IntKakutei int --確定ステータス 16Declare @VarQuery1 varchar(max)--確定ステータスが未確定の時に使用するクエリ(全カラム更新) 17Declare @VarQuery2 varchar(max)--確定ステータスが確定の時に使用するクエリ(一部のカラムを更新) 18 19SET @VarQuery1 = 'UPDATE [dbo].[テーブルA_WK] ' 20+ 'SET [dbo].[テーブルA_WK].カラム1 = inserted.カラム1' 21+ ', [dbo].[テーブルA_WK].カラム2 = inserted.カラム2' 22+ ', [dbo].[テーブルA_WK].カラム3 = inserted.カラム3' 23+ ', [dbo].[テーブルA_WK].カラム4 = inserted.カラム4' 24+ ', [dbo].[テーブルA_WK].カラム5 = inserted.カラム5' 25+ ', [dbo].[テーブルA_WK].更新者 = inserted.更新者' 26+ ', [dbo].[テーブルA_WK].更新時間 = inserted.更新時間 ' 27+ 'FROM [dbo].[テーブルA_WK] ' 28+ 'INNER JOIN inserted ' 29+ 'ON [dbo].[テーブルA_WK].番号 = inserted.番号 ' 30+ 'WHERE [dbo].[テーブルA_WK].番号 = ' 31 32SET @VarQuery2 = 'UPDATE [dbo].[テーブルA_WK] ' 33+ 'SET [dbo].[テーブルA_WK].カラム4 = inserted.カラム4' 34+ ', [dbo].[テーブルA_WK].カラム5 = inserted.カラム5' 35+ ', [dbo].[テーブルA_WK].更新者 = inserted.更新者' 36+ ', [dbo].[テーブルA_WK].更新時間 = inserted.更新時間 ' 37+ 'FROM [dbo].[テーブルA_WK] ' 38+ 'INNER JOIN inserted ' 39+ 'ON [dbo].[テーブルA_WK].番号 = inserted.番号 ' 40+ 'WHERE [dbo].[テーブルA_WK].番号 = ' 41 42--カーソル定義 43DECLARE MY_CUR CURSOR FOR 44 SELECT 番号 45 FROM inserted 46 47--カーソルオープン 48OPEN MY_CUR; 49 50--最初の1行目を取得して変数へ値をセット 51FETCH NEXT FROM MY_CUR 52INTO @VarBangou 53 54--データの行数分ループ処理を実行する 55WHILE @@FETCH_STATUS = 0 56BEGIN 57 58-- ========= ループ内の実際の処理 ここから ========= -- 59--データが存在する 60IF EXISTS (SELECT * FROM [dbo].[テーブルA_WK] WHERE 番号 = @VarBangou) 61BEGIN 62 --確定ステータスを取得 63 SET @IntKakutei = (SELECT フラグ2 FROM [dbo].[テーブルB_WK] WHERE 番号 = @VarBangou) 64 PRINT 'このデータの確定ステータスは' + CONVERT(varchar, @IntKakutei) + 'です。' 65 --未確定 66 IF @IntKakutei = 0 67 BEGIN 68 PRINT '未確定ですので全カラムで更新します。' 69 EXEC(@VarQuery1 + @VarBangou) 70 END 71 --確定 72 ELSE 73 BEGIN 74 PRINT '確定ですので一部のカラムを更新します。' 75 EXEC(@VarQuery2 + @VarBangou) 76 END 77END 78-- ========= ループ内の実際の処理 ここまで ========= -- 79 80 81--次の行のデータを取得して変数へ値をセット 82FETCH NEXT FROM MY_CUR 83INTO @VarBangou 84 85END 86 87--カーソルを閉じる 88CLOSE MY_CUR; 89DEALLOCATE MY_CUR; 90 91 92END 93/***********トリガー END ***********/
EXECの部分でinsertedが無効と言われてしまいます。
試しに、変数に入れずにクエリをベタ書きで実行するとうまく処理が流れてくれます。
ただ可読性の部分で、できれば変数にいれて実行したいのですが、いい方法はありますでしょうか??
insertedをワークテーブルに入れてそこを指定するというやり方はとりあえずは無しです。
どうかご教授のほどよろしくお願いします。
エラーに関する解決策ではないので、こちらにコメントしますが、
以下の様な記述にすれば、SQLは1パターンで可能だと思いますので、制御文が不要になり直接SQLを記述しても可読性は上げられると思います。
set カラム1 = case when @IntKakutei=0 then inserted.カラム1 else カラム1 end
また、executeを使用すると、文字列のSQLに関してはコンパイルエラーにならず、実行時にしかエラーにはならないので、直接SQL文を記述するようにした方が、効率的には上だと思います。
ではべた書きで実行する方法でいきます!
ありがとうございます。
べた書きと言うか、そもそも動的SQLにする必要性が無いものを動的にしている方が変です。
確かに、、、、
あなたの回答
tips
プレビュー