web-dev-qa-db-ja.com

スカラー変数エラーを宣言する必要があります

私の構文は、私が思うように私の心を吹き飛ばしている(そして私が間違っている場合は親切に訂正してください)以下のエラーを繰り返し出します。この変数を宣言して設定しました。

メッセージ137、レベル15、状態2、行1
スカラー変数「@id」を宣言する必要があります。

これが私の構文です。print @idステートメントを含めると、適切な値が出力されますが、それでも上記のエラーが発生しますか?!

Create Table #temphold
(
  dateadded datetime
  ,dateupdated datetime
  ,id varchar(100)
)

Declare @id varchar(100), @sql varchar(max)
Set @id = '12345'


set @sql = 'insert into   #temphold(dateadded,dateupdated,id) '
          +'select   getdate(),getdate(),COALESCE(@id,'''') '
PRINT @SQL
EXEC(@SQL)


Drop Table #temphold
1
Michael Mormon

実行変数の一部としての@id @sqlは何もしていません。周囲の文字列を構築する、つまり次のように文字列に連結しない限り、それは宣言された変数に関連付けられません。

set @sql = 'insert into #temphold(dateadded,dateupdated,id) ' +'select getdate(),getdate(),COALESCE(' + @id + ','''') '

+ @変数の両側に注意してください。

結局、EXEC()コマンドを使用して実行されるまで、@ sqlは単なる文字列です。完全に修飾されたT-SQLとしてコンパイルされるまで、そのまま扱います。

2
Molenpad

@idをリテラルとしてではなく、動的クエリにパラメータとして渡すこともできます。これを行うには、EXECの代わりにsp_executesql関数を使用する必要があります。 IMOがパラメーターをステートメントに渡すと、生成されたステートメントがもう少し明確/読みやすくなり、特定のデータ型をnvarcharにキャストまたは変換する必要がなくなります。このようにすると、SQL Serverが再利用できるクエリプランを生成する可能性が高くなります。

これは、いくつかの比較と対比を提供するスタックオーバーフローに関する投稿です。 ストアドプロシージャEXECとsp_executesqlの違い?

こちらが Microsoftのtechnetsp_executesqlに関する記事です。

Create Table #temphold
(
  dateadded datetime
  ,dateupdated datetime
  ,id varchar(100)
)

Declare @id varchar(100), @sql nvarchar(max)
Set @id = '12345'


set @sql = 'insert into   #temphold(dateadded,dateupdated,id) '
          +'select   getdate(),getdate(),COALESCE(@id,'''') '
PRINT @SQL;
execute sp_executesql @statement = @sql, @parameters = N'@id varchar(100)', @id = @id

Drop Table #temphold
2
Aaron

変数@sql onlyは、定義された場所に存在します。定義は「GO」ステートメントで区切られます。これがうまくいくかどうか確認してください...

Set @id = '12345'
Set @sql = 'insert into   #temphold(dateadded,dateupdated,id) '
          +'select   getdate(),getdate(),COALESCE(@id,'''') '
GO
PRINT @sql;
execute sp_executesql @statement = @sql, @parameters = N'@id varchar(100)', @id = @id

Drop Table #temphold
0
Mark McKelvy