sql >> データベース >  >> RDS >> Sqlserver

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

    このブログ投稿のテストによると、SQL Serverは、CommandType.Textを使用するときに、ステートメントをsp_executesqlでラップすることにより、パラメーター化を行います。 。ただし、CommandType.StoredProcedureを使用する場合 あなたはそれをパラメータ化し、それによってデータベースにいくらかの作業を保存します。後者の方法の方が高速です。

    編集:

    セットアップ

    私は自分でいくつかのテストを行いました。結果は次のとおりです。

    次の手順を作成します:

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

    SQLServerプロファイラーを使用してトレースを追加します。

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

    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プロシージャまたは関数「テスト」には、指定されていないパラメータ「@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を使用している場合 、次に、デフォルト値を使用する場合を除いて、プロシージャの呼び出しにパラメータ名を追加する必要があります。


    1. CentOS7へのMySQLのインストール

    2. SQLiteとデータベースの初期化

    3. 実際の使用法とSQLiteドキュメントのコンテキストで、EnableWriteAheadLoggingはどの程度スレッドセーフですか?

    4. バックアップからのMySQLまたはMariaDBGaleraクラスターの完全な復元