De acordo com os testes nesta postagem do blog, o SQL Server fará a parametrização para você, envolvendo sua instrução em sp_executesql, quando você usar
CommandType.Text
. Mas quando você usa CommandType.StoredProcedure
você irá parametrizá-lo e assim poupar algum trabalho ao banco de dados. O último método é mais rápido. Editar:
Configuração
Eu mesmo fiz alguns testes e aqui estão os resultados.
Crie este procedimento:
create procedure dbo.Test
(
@Text1 varchar(10) = 'Default1'
,@Text2 varchar(10) = 'Default2'
)
as
begin
select @Text1 as Text1, @Text2 as Text2
end
Adicione um rastreamento a ele usando o SQL Server Profiler.
E, em seguida, chame-o usando o seguinte código:
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"]);
}
}
}
}
}
}
}
Resultados
Em ambos os casos as chamadas são feitas usando RPC.
Veja o que o rastreamento revela usando
CommandType.Text
:exec sp_executesql N'dbo.Test',N'@Text1 nvarchar(5),@Text2 nvarchar(5)',@Text1=N'Text1',@Text2=N'Text2'
E aqui está o resultado usando
CommandType.StoredProcedure
:exec dbo.Test @Text1=N'Text1',@Text2=N'Text2'
Como você pode ver, a chamada de texto é envolvida em uma chamada para
sp_executesql
para que esteja devidamente parametrizado. É claro que isso criará uma pequena sobrecarga e, portanto, minha declaração anterior de que usar CommandType.StoredProcedure
é mais rápido ainda está de pé. Outra coisa digna de nota, e que também é meio que um deal breaker aqui, é que quando criei a procedure sem valores default recebi o seguinte erro:
Msg 201, Nível 16, Estado 4, Teste de Procedimento, Linha 0 O procedimento ou função 'Teste' espera o parâmetro '@Text1', que não foi fornecido.
A razão para isso é como a chamada para
sp_executesql
é criado, como você pode ver os parâmetros são declarados e inicializados, mas não são usados . Para a chamada funcionar, deveria ter ficado assim:exec sp_executesql N'dbo.Test @Text1, @Text2',N'@Text1 nvarchar(5),@Text2 nvarchar(5)',@Text1=N'Text1',@Text2=N'Text2'
Ou seja, quando você está usando
CommandType.Text
você tem que adicionar os parâmetros ao CommandText
a menos que você sempre queira que os valores padrão sejam usados. Então, para responder à sua pergunta
- Usando
CommandType.StoredProcedure
é mais rápido. - Se você estiver usando
CommandType.Text
, você terá que adicionar os nomes dos parâmetros à chamada do procedimento, a menos que queira que os valores padrão sejam usados.