Sqlserver
 sql >> Datenbank >  >> RDS >> Sqlserver

Welchen Vorteil hat die Verwendung von CommandType.StoredProcedure gegenüber der Verwendung von CommandType.Text beim Ausführen einer gespeicherten Prozedur?

Gemäß den Tests in diesem Blogbeitrag übernimmt SQL Server die Parametrisierung für Sie, indem es Ihre Anweisung in sp_executesql einschließt, wenn Sie CommandType.Text verwenden . Aber wenn Sie CommandType.StoredProcedure verwenden Sie werden es parametrisieren und dadurch der Datenbank etwas Arbeit ersparen. Die letztere Methode ist schneller.

Bearbeiten:

Einrichtung

Ich habe selbst einige Tests durchgeführt und hier sind die Ergebnisse.

Erstellen Sie diese Prozedur:

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

Fügen Sie mit SQL Server Profiler eine Ablaufverfolgung hinzu.

Rufen Sie es dann mit dem folgenden Code auf:

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"]);
                        }
                    }
                }
            }
        }
    }
}

Ergebnisse

In beiden Fällen erfolgen die Aufrufe über RPC.

Folgendes zeigt die Ablaufverfolgung mit CommandType.Text :

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

Und hier ist das Ergebnis mit CommandType.StoredProcedure :

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

Wie Sie sehen können, ist der Textaufruf in einen Aufruf von sp_executesql eingeschlossen damit es richtig parametriert ist. Dies erzeugt natürlich einen leichten Overhead, und daher meine vorherige Aussage, dass CommandType.StoredProcedure verwendet wird ist schneller noch steht.

Eine weitere bemerkenswerte Sache, die hier auch eine Art Deal Breaker ist, ist, dass ich beim Erstellen der Prozedur ohne Standardwerte den folgenden Fehler erhalten habe:

Msg 201, Level 16, State 4, Procedure Test, Line 0 Die Prozedur oder Funktion „Test“ erwartet den Parameter „@Text1“, der nicht angegeben wurde.

Der Grund dafür ist der Aufruf von sp_executesql erstellt, wie Sie sehen können, werden die Parameter deklariert und initialisiert, aber sie werden nicht verwendet . Damit der Aufruf funktioniert, sollte er so aussehen:

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

Das heißt, wenn Sie CommandType.Text verwenden Sie müssen die Parameter zum CommandText hinzufügen es sei denn, Sie möchten immer die Standardwerte verwenden.

Um Ihre Frage zu beantworten

  1. Mit CommandType.StoredProcedure ist schneller.
  2. Wenn Sie CommandType.Text verwenden , dann müssen Sie die Parameternamen zum Aufruf der Prozedur hinzufügen, es sei denn, Sie möchten, dass die Standardwerte verwendet werden.