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

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

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

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

Q&A

解決済

1回答

1066閲覧

ストアドで可変的にSOL文(UPDATE文)を生成したい

hiro_hiro_hiro

総合スコア42

SQL Server

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

0グッド

0クリップ

投稿2019/02/19 01:19

編集2019/02/19 06:55

前提・実現したいこと

SQLSERVERのデータベースの値からデータベース名、フィールド名を抜出をし、
抜出したデータベース名からを参照し、
ストアドから可変的データベースを参照するSQL文(UPDATE文)を実行したい。

発生している問題・エラーメッセージ

Pテーブル

1S     LotNo Retrying 2CAAA001  CAAA  3CAAA002  CAAA 4CAAA003  CAAA 5 6Vテーブル 7 S     LotNo VResult LatestData 8 CAAA001  CAAA 0     1 9 CAAA001  CAAA 5     0 10 CAAA002  CAAA 0     1 11 CAAA003  CAAA 5     1 12      ↓ 13Pテーブル 14 S     LotNo Retrying 15CAAA001  CAAA   16CAAA002  CAAA   17CAAA003  CAAA  7100 18にしたい 19 20文章は実行されるがうまく式が動作しない、

該当のソースコード

SOL server

1 @DB as varchar(50), -- 別テーブル名 2 @DB2 as varchar(50), -- 別テーブル フィールド名1 3 @DB3 as varchar(50), -- 別テーブル フィールド名2 4 @LotNO as varchar(12), -- UPDATE テーブルと別テーブルの共通する値 5 @Retrying as varchar(50), --入れたい情報1 6 @RetryingRegistWorker as nchar(12), --入れたい情報2 7 @RetryingScheduleDay as varchar(50) --入れたい情報3 8 9AS 10DECLARE @Magu AS int 11DECLARE @RCNT AS int 12DECLARE @InnerSQL NVARCHAR(2000) 13 14SET XACT_ABORT ON 15BEGIN TRAN 16 17SET @InnerSQL = 'UPDATE ProductRecord 18 SET ProductRecord.Retrying = ' + @Retrying + 19 ',ProductRecord.RetryingRegistWorker =' + @RetryingRegistWorker + 20 ',ProductRecord.RetryingRegistDay = GETDATE () 21 ,ProductRecord.RetryingScheduleDay =' + @RetryingScheduleDay + 22 ',ProductRecord.RetryingExecutDay = ' + Null + 23 ',ProductRecord.UpdatedDay = GETDATE () 24 WHERE EXISTS 25 (SELECT * 26 FROM '+ @DB + 27 'WHERE ProductRecord.LotNo =' + @LotNO + 28 'AND ProductRecord.LotNo = ' + @DB + '.LotNo)' 29 30EXEC (@InnerSQL) 31 SET @RCNT = @@ROWCOUNT 32 33 COMMIT TRAN 34RETURN @RCNT

試したこと

最初は sp_executesql を使ってやっていたが うまくいかなかったためEXEC単体にシフトチェンジした。

補足情報(FW/ツールのバージョンなど)

ここにより詳細な情報を記載してください。

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

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

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

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

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

hihijiji

2019/02/19 01:44

ご自身で書かれたコードの色に着目してみて下さい。
hiro_hiro_hiro

2019/02/19 06:13

こちらでの投稿が初めてでお伺いしたいのですが、コードが赤になってるとエラーになっているという事でしょうか?
hihijiji

2019/02/19 07:16

失礼しました。 よく見たらここのコード解析自体が上手く動いてなくて色がおかしくなってたのですね。
hiro_hiro_hiro

2019/02/19 07:25

いえいえ、ご指摘ありがとうございます。
guest

回答1

0

ベストアンサー

ぱっと見SQL文が正しく生成されていないように見受けられます。
記述上は改行されていますが、式としては文字列の結合なのでfromwhereが区切られていなかったり、
文字型の更新に、文字区切記号(')が入っていなかったりしているのではないでしょうか。

@InnerSQLに生成されているSQLを取り出して、直接実行してみればエラー内容が明確になると思います。

追記

SQL

1UPDATE P SET Retrying=7100 2WHERE exists( 3 SELECT 1 FROM V 4 WHERE VResult=5AND LatestData='1' AND LotNo=p.LotNo and s=p.s 5 ) 6 and LotNo='CAAA'

複数のLotNo に対して一括で行うなら

SQL

1UPDATE P SET Retrying=case LotNo when 'CAAA' then 7100 when 'CEND' then 7104 end 2WHERE exists( 3 SELECT 1 FROM V 4 WHERE VResult=5AND LatestData='1' AND LotNo=p.LotNo and s=p.s 5 ) 6 and LotNo in ('CAAA', 'CEND')

投稿2019/02/19 01:49

編集2019/02/19 07:29
sazi

総合スコア25173

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

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

hiro_hiro_hiro

2019/02/19 04:39

回答ありがとうございます。 最終的には、Vのテーブルから最新値(V.LatestData = '1')で検査結果が5 (V.VResult = '5')のVのテーブルの共通フィールド(LotNo)を抽出し、 その値でPテーブルにソートをかけ、該当するフィールドに値を代入したいです。 アドバイス通り、別のストアドを作り、元の値で実行しているのですが、うまくいきません。 V.LatestDataとV.VResultはint型です。 2パターン試しましたが、Vのテーブルのソートが上手くいきませんでした。 パターン1 UPDATE P SET P.Retrying = 7100 WHERE EXISTS (SELECT * FROM V WHERE V.VResult = ’5’ AND V.LatestData = '1' AND V.LotNo = 'CAAA' AND P.LotNo = V.LotNo ) パターン2 UPDATE P SET P.Retrying = 7104 FROM P INNER JOIN V ON P.LotNo = V.LotNo AND V.VResult = 5 AND V.LatestData = 1 AND V.LotNo = 'CEND'
sazi

2019/02/19 04:46

上手くいかないとは?エラーになる?更新されない?
hiro_hiro_hiro

2019/02/19 05:38

説明不足で申し訳ありません。 エラーにはなりません。 パターン1の場合 更新自体がされません パターン2の場合 AND V.VResult = 5 AND V.LatestData = 1 を無視して、 P.LotNO = 'CEND' のデータが更新されてしまいます。
sazi

2019/02/19 06:14

パターン1は下記と同じ内容ですけど、やりたいことは合っていますか? UPDATE P SET Retrying=7100 WHERE LotNo='CAAA' and exists( SELECT 1 FROM V WHERE VResult=’5’AND LatestData='1' AND LotNo='CAAA' )
hiro_hiro_hiro

2019/02/19 06:45

Pテーブル S     LotNo Retrying CAAA001 CAAA  CAAA002 CAAA CAAA003 CAAA Vテーブル S     LotNo VResult LatestData CAAA001 CAAA 0     1 CAAA001 CAAA 5     0 CAAA002 CAAA 0     1 CAAA003 CAAA 5     1       ↓ Pテーブル S     LotNo Retrying CAAA001 CAAA   CAAA002 CAAA   CAAA003 CAAA  7100 になるイメージです。 書いてくださった式で実行してみたのですが、 Pテーブル S     LotNo Retrying CAAA001 CAAA   CAAA002 CAAA  7100  CAAA003 CAAA  7100 という風になってしまって、CAAA001以外 Vテーブルの値を参照してないような感じでした。
sazi

2019/02/19 06:49

Sという項目の関係について何も行っていないからだと思います。 テーブルのデータや定義はこのコメント欄に書かずに、質問を編集して追記して下さい。
hiro_hiro_hiro

2019/02/19 07:11

ご指摘、ありがとうございます。 当方初めての投稿なので非常にありがたいです。 テーブルの情報を発生している問題の所に追記しました。 つまり、この処理では、1つのデータしか処理できないので、ループ処理等でSのデータ個数分読み込ませる処理をしなければ、いけないという認識でよろしいでしょうか?
sazi

2019/02/19 07:30

追記しました。
hiro_hiro_hiro

2019/02/19 07:45

ありがとうございます!無事処理できました! 昨日の午後からすごく悩んでいた事象だったので感動しました! ベストアンサーにさせて頂きます!本当にありがとうございました!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問