Sqlserver
 sql >> Base de Dados >  >> RDS >> Sqlserver

Ao executar um procedimento armazenado, qual é a vantagem de usar CommandType.StoredProcedure versus usar CommandType.Text?


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
  1. Usando CommandType.StoredProcedure é mais rápido.
  2. 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.