declare @sql varchar(100) = 'select 1+1' execute( @sql)
1. Executeを介して行を実行すると、現在の変数は表示されませんが、すべての一時テーブルが表示されるコードブロックが個別に作成されます。
2. NULL値を持つ変数の受け渡しに注意してください。 NULLとのマージはNULLになります。したがって、クエリを実行する代わりに、空の文字列を取得できます。
declare @i int declare @sql varchar(100) = 'select ' + cstr(@i) execute( @sql ) --
3.日付と時刻を転送します。 日付はYYYYMMDD形式で送信するのが最適です。 経時的にパラメーターを渡す場合、精度の低下に注意する必要があります。 精度を維持するには、一時テーブルを介して値を渡すのが最善です。
4.浮動小数点でパラメーターを渡すことには、構築されたクエリ内で時間を渡すことと同じ問題があります。
5.文字列値-潜在的に危険なコード。 まず、文字列内ですべての単一引用符を複製する必要があります。 文字列自体は一重引用符で囲まれます。
エラーコードの例:
Declare @str varchar(100) = 'Number ''1'' ' Declare @sql varchar(1000) = 'select String = '+ IsNull( '''' + @str + '''', 'null' ) Execute( @sql ) --
正しいコードは次のとおりです。
Declare @str varchar(100) = 'Number ''1'' ' Declare @sql varchar(1000) = 'select String = '+ IsNull( '''' + replace( @str, '''', '''''') + '''', 'null' ) Execute( @sql )
6.セクションINのリストの置換。 主な危険は空のリストです。 この場合、セクションは「フィールドIN()」のようになり、コンパイル中にエラーが発生します。 闘争の方法として:常にリストの先頭にNULLを含めるか、空の文字列をNULLに置き換えます。 NULLは任意のデータ型と比較できます。 NULLとの比較では常に負の結果が得られますが、リストは空ではないことが保証されています。
Declare @list varchar(100) = '' iif @list = '' set @list = 'null' Declare @sql varchar(1000) = 'select number from documents where id in ('+@list+') ' Execute( @sql )
一時テーブルを介して複雑なパラメータを安全に渡す例を次に示します。
if OBJECT_ID('tempdb..#params') is not null drop table #params create table #params ( v1 int, v2 datetime, v3 varchar(100) ) insert #params values ( 1, getdate(), ' ''1''') declare @sql varchar(1000) = ' declare @v1 int, @v2 datetime, @v3 varchar(100) select @v1 = v1 , @v2 = v2, @v3 = v3 from #params select @v1, @v2, @v3 ' execute(@sql) drop table #params
さて、ちょっとした前菜の場合:
最初に変数を介して転送されたパラメーターを宣言し、これらの変数を初期化し、計算中にこれらの変数を使用することをお勧めします。 この場合、クエリテキストの読みやすさが向上し、デバッグが容易になります。
変数を使用しない場合、次の方法を使用できます。
set @sql = 'select <VAR1> + <VAR2>' set @sql = replace(@sql, '<VAR1>', '1') set @sql = replace(@sql, '<VAR2>', '2') execute( @sql )
上記の機能に加えて、パラメーターを渡す方法がいくつかあります。
1. sp_executesqlを使用します(コメントでプロンプトが表示されます)
2.リクエストを一時的なストアドプロシージャにラップして実行します。 開始回数が多い場合、この方法はさらに効果的です。
declare @sql varchar(200) = ' create procedure #test ( @p1 int, @p2 int) as select @p1 + @p2' execute( @sql ) exec #test 1, 2 exec #test 3,4 drop procedure #test