T-SQL - sp_executesqlを使ったクエリの実行を確認する
EF CoreやADO.NETでは、パラメーターがあるSELECT文などを実行するときにsp_executesqlストアドプロシージャが使われます。
SqlCommand Class (Microsoft.Data.SqlClient) | Microsoft Learn
Remarksの表にあるExecuteReaderの説明には次のようにあります。
Executes commands that return rows. For increased performance, ExecuteReader invokes commands using the Transact-SQL sp_executesql system stored procedure.
行を返すコマンドを実行します。パフォーマンスを向上させるために、ExecuteReaderはTransact-SQLのsp_executesqlシステムストアドプロシージャを使用してコマンドを呼び出します。
そういえばsp_executesqlは手が書いて実行したことがないなと思ったので、sp_executesqlを使ったクエリを確認してみました。
sp_executesql (Transact-SQL) - SQL Server | Microsoft Learn
パラメーターを1つ渡す
パラメーターを1つ渡す場合は次のようにします。
execute sp_executesql
-- SQL文
N'select @p as value',
-- パラメーター名+型
N'@p int',
-- パラメーターの値
'1';
-- 実行結果
/*
Value
1
*/
引数のパラメーター名を指定する場合は以下のようになります。
パラメーターの値は、@pのようにSQL文内に埋め込むパラメーター名を指定します。
-- パラメーター名を指定する場合
execute sp_executesql
@stmt = N'select @p as Value',
@params = N'@p int',
@p = '1';
パラメーターを2つ(複数)渡す
パラメーターを2つ渡す場合です。
パラメーターの型を指定(@params)では、@p1 int, @p2 intのようにカンマ区切りで複数のパラメーターを指定します。
execute sp_executesql
N'select @p1 as Value1, @p2 as Value2',
N'@p1 int, @p2 int',
'1',
'2';
-- 実行結果
/*
Value1 Value2
1 2
*/
-- パラメーター名を指定する場合
execute sp_executesql
@stmt = N'select @p1 as Value1, @p2 as Value2',
@params = N'@p1 int, @p2 int',
@p1 = '1',
@p2 = '2';
OUT、OUTPUTパラメーターを使う
OUT、OUTPUTパラメーターを使う場合は、次のように指定します。どうもoutのキーワードを2カ所指定する必要があるようです。
declare @p int;
execute sp_executesql
N'select @p = 1',
N'@p int out',
@p out;
select @p as Value;
-- 実行結果
/*
Value
1
*/
変数を使ってストアドプロシージャを呼び出す
sp_executesqlの引数は文字列なので、SQL文やパラメーターを文字列変数に格納して実行することもできます。
declare @statement nvarchar(50) = N'select @p as Value';
declare @parameters nvarchar(50) = N'@p int';
declare @value varchar(50) = '1';
execute sp_executesql
@statement,
@parameters,
@value;
-- 実行結果
/*
Value
1
*/
sp_executesqlを使ってみましたというお話でした。