質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.35%
SQL Server

SQL Serverはマイクロソフトのリレーショナルデータベース管理システムです。データマイニングや多次元解析など、ビジネスインテリジェンスのための機能が備わっています。

Q&A

0回答

1940閲覧

SQL Server トリガーでSQL文を変数に入れて実行したい

Chandler_Bing

総合スコア673

SQL Server

SQL Serverはマイクロソフトのリレーショナルデータベース管理システムです。データマイニングや多次元解析など、ビジネスインテリジェンスのための機能が備わっています。

0グッド

0クリップ

投稿2021/10/27 01:07

お世話になっております。

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をワークテーブルに入れてそこを指定するというやり方はとりあえずは無しです。

どうかご教授のほどよろしくお願いします。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

sazi

2021/10/27 01:38

エラーに関する解決策ではないので、こちらにコメントしますが、 以下の様な記述にすれば、SQLは1パターンで可能だと思いますので、制御文が不要になり直接SQLを記述しても可読性は上げられると思います。 set カラム1 = case when @IntKakutei=0 then inserted.カラム1 else カラム1 end
sazi

2021/10/27 01:41

また、executeを使用すると、文字列のSQLに関してはコンパイルエラーにならず、実行時にしかエラーにはならないので、直接SQL文を記述するようにした方が、効率的には上だと思います。
Chandler_Bing

2021/10/27 01:45

ではべた書きで実行する方法でいきます! ありがとうございます。
sazi

2021/10/27 02:10

べた書きと言うか、そもそも動的SQLにする必要性が無いものを動的にしている方が変です。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだ回答がついていません

会員登録して回答してみよう

アカウントをお持ちの方は

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.35%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問