Sqlserver
 sql >> Database >  >> RDS >> Sqlserver

Quando si esegue una stored procedure, qual è il vantaggio dell'utilizzo di CommandType.StoredProcedure rispetto all'utilizzo di CommandType.Text?

Secondo i test in questo post del blog, SQL Server eseguirà la parametrizzazione per te, avvolgendo la tua istruzione in sp_executesql, quando usi CommandType.Text . Ma quando usi CommandType.StoredProcedure lo parametrizzerai e quindi risparmierai un po' di lavoro nel database. Quest'ultimo metodo è più veloce.

Modifica:

Configurazione

Ho fatto alcuni test io stesso ed ecco i risultati.

Crea questa procedura:

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

Aggiungi una traccia utilizzando SQL Server Profiler.

E poi chiamalo usando il seguente codice:

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

Risultati

In entrambi i casi le chiamate vengono effettuate tramite RPC.

Ecco cosa rivela la traccia usando CommandType.Text :

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

Ed ecco il risultato usando CommandType.StoredProcedure :

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

Come puoi vedere, la chiamata di testo è racchiusa in una chiamata a sp_executesql in modo che sia parametrizzato correttamente. Questo ovviamente creerà un leggero sovraccarico, e quindi la mia precedente affermazione che usando CommandType.StoredProcedure è più veloce è ancora in piedi.

Un'altra cosa degna di nota, e che è anche una specie di problema qui, è che quando ho creato la procedura senza valori predefiniti ho ricevuto il seguente errore:

Msg 201, Livello 16, Stato 4, Test procedura, Riga 0 La procedura o la funzione 'Test' prevede il parametro '@Text1', che non è stato fornito.

Il motivo è come la chiamata a sp_executesql viene creato, come puoi vedere i parametri sono dichiarati e inizializzati, ma non vengono utilizzati . Affinché la chiamata funzioni, dovrebbe essere simile a questa:

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

Significato, quando stai usando CommandType.Text devi aggiungere i parametri al CommandText a meno che tu non voglia sempre utilizzare i valori predefiniti.

Quindi, per rispondere alla tua domanda

  1. Utilizzo di CommandType.StoredProcedure è più veloce.
  2. Se stai usando CommandType.Text , quindi dovrai aggiungere i nomi dei parametri alla chiamata alla procedura a meno che tu non voglia utilizzare i valori predefiniti.