ストアド プロシージャを実行する場合、CommandType.StoredProcedure を使用する場合と CommandType.Text を使用する場合の利点は何ですか? 質問する

ストアド プロシージャを実行する場合、CommandType.StoredProcedure を使用する場合と CommandType.Text を使用する場合の利点は何ですか? 質問する

したがって、C# でストアド プロシージャを使用するには、次のようなコードを使用します (接続コードは省略)。

 string sql = "GetClientDefaults";

 SqlCommand cmd = new SqlCommand(sql);
 cmd.CommandType = CommandType.StoredProcedure;    //<-- DO I NEED THIS??
 cmd.Parameters.AddWithValue("@computerName", computerName);

ここで、sql はストアド プロシージャの名前です。このコードは、コメント行の有無にかかわらず正常に動作するようです。

それで、この行は必要ですか? これを設定すると、パフォーマンス (またはその他の) 上の利点がありますか? 設定しない、または Text に設定すると利点がありますか?

ベストアンサー1

テストによるとこのブログ投稿を使用すると、SQL Server はステートメントを sp_executesql でラップしてパラメーター化を行いますCommandType.Text。ただし、 を使用すると、CommandType.StoredProcedureステートメントをパラメーター化して、データベースの作業を節約できます。後者の方法の方が高速です。

編集:

設定

私自身もいくつかテストをしてみましたが、結果は次の通りです。

次の手順を作成します。

create procedure dbo.Test
(
   @Text1 varchar(10) = 'Default1'
  ,@Text2 varchar(10) = 'Default2'
)
as
begin
   select @Text1 as Text1, @Text2 as Text2
end

SQL Server Profiler を使用してトレースを追加します。

そして、次のコードを使用して呼び出します。

using System;
using System.Data;
using System.Data.SqlClient;

namespace ConsoleApplication2
{
    class Program
    {
        static void Main()
        {
            CallProcedure( CommandType.Text );
            CallProcedure( CommandType.StoredProcedure );
        }

        private static void CallProcedure(CommandType commandType)
        {
            using ( SqlConnection connection = new SqlConnection("Data Source=localhost;Initial Catalog=Test;Integrated Security=SSPI;") )
            {
                connection.Open();
                using ( SqlCommand textCommand = new SqlCommand("dbo.Test", connection) )
                {
                    textCommand.CommandType = commandType;
                    textCommand.Parameters.AddWithValue("@Text1", "Text1");
                    textCommand.Parameters.AddWithValue("@Text2", "Text2");
                    using ( IDataReader reader = textCommand.ExecuteReader() )
                    {
                        while ( reader.Read() )
                        {
                            Console.WriteLine(reader["Text1"] + " " + reader["Text2"]);
                        }
                    }
                }
            }
        }
    }
}

結果

どちらの場合も、呼び出しは RPC を使用して行われます。

トレースで明らかになった内容は次のとおりですCommandType.Text:

exec sp_executesql N'dbo.Test',N'@Text1 nvarchar(5),@Text2 nvarchar(5)',@Text1=N'Text1',@Text2=N'Text2'

以下は、を使用した結果ですCommandType.StoredProcedure

exec dbo.Test @Text1=N'Text1',@Text2=N'Text2'

ご覧のとおり、テキスト呼び出しは、sp_executesql適切にパラメータ化されるように、呼び出しにラップされています。もちろん、これによって若干のオーバーヘッドが発生しますが、 を使用する方が高速であるという以前の説明はCommandType.StoredProcedure変わりません。

もう 1 つ注目すべき点 (そして、ここでの決定的な要因でもある) は、デフォルト値なしでプロシージャを作成したときに次のエラーが発生したことです。

メッセージ 201、レベル 16、状態 4、プロシージャ テスト、行 0 プロシージャまたは関数 'Test' にはパラメーター '@Text1' が必要ですが、指定されていません。

その理由は、呼び出しがどのようにsp_executesql作成されるかです。ご覧のとおり、パラメータが宣言され、初期化されています。しかし、それらは使われていない呼び出しが機能するには、次のようになります。

exec sp_executesql N'dbo.Test @Text1, @Text2',N'@Text1 nvarchar(5),@Text2 nvarchar(5)',@Text1=N'Text1',@Text2=N'Text2'

つまり、常にデフォルト値を使用する場合を除き、 を使用するときCommandType.Textにパラメータを追加する必要があります。CommandText

それで、あなたの質問に答えると

  1. 使用するCommandType.StoredProcedureと速くなります。
  2. を使用している場合はCommandType.Text、デフォルト値を使用する場合を除き、プロシージャの呼び出しにパラメータ名を追加する必要があります。

おすすめ記事