2017年3月18日土曜日

sp_executesql でパラメーターを変更しながらSQL文を実行

SQLServer の話題です。

ストアドで動的に作成したSQL文を実行したい場合に有効な手段です。

Execute sp_executesql @実行したいSQL文,
                                 @SQL文の中で使うパラメーターの型宣言,
                                 @パラメーターそれぞれの内容

という構文になります。

実際には、
-------------------------------------------------------------------
Declare @strSQL nvarchar(1000)
Declare @prm nvarchar(1000)
Declare @A_MAX

Set @strSQL = 'Select @prm_MAX = MAX(ColA) as A_MAX From T_tableA Where ColB = @prm_B'
Set @prm = '@prm_MAX int OUTPUT ,@prm_B nvarchar(200)'

execute sp_executesql @strSQL,@prm,@prm_MAX = @A_MAX OUTPUT,@prm_B = '東京都'

Select @A_MAX as ColAの最大

-------------------------------------------------------------------

主となるSQL文(@strSQL)内で、パラメーターを2個使う例です。

1個は ColAの最大値を求めて、表示するための @prm_MAX、
もう1個は、条件で使用するための @prm_B

@prm は主となるSQL文内で使うため専用の宣言を行うパートです。
executesql 専用 Declare って感じですね。

この例では、@prm_MAX を外に出しますので、「OUTPUT」を付けます。

execitesql の最後のパートは、SQL文内で使うパラメーターの実際の値を書きます。
ここでも、外に出すパラメーターには「OUTPUT」を付けます。
ここで勘違いしやすいのが、赤で塗ってある部分です。
普通の変数に値を代入する感覚では、「@A_MAX = @prm_MAX」となるのですが、ここでは、SQL文内のパラメーターを中心に考えるので、逆に書くことになり、
「@prm_MAX = @A_MAX」で正解です。
これで、@A_MAX に@prm_MAX の内容が代入されます。なんか変な感じですね。

@prm_B は簡単ですね。

最終的に、SQL文内で使ったパラメーターはあくまでも内部専用のパラメーターですから、外部に出してくるための@A_MAX は事前に Declare で宣言が必要です。

当たり前ですが、SQL文内にあるパラメーターの個数と、宣言文内での個数と、実際の値を与えるパートの個数が一致しないとエラーになります。