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
- Utilizzo di
CommandType.StoredProcedure
è più veloce. - 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.