Zgodnie z testami w tym wpisie na blogu, SQL Server dokona parametryzacji za Ciebie, umieszczając Twoją instrukcję w sp_executesql, gdy użyjesz CommandType.Text
. Ale kiedy używasz CommandType.StoredProcedure
sparametryzujesz go, oszczędzając w ten sposób bazę danych. Ta druga metoda jest szybsza.
Edytuj:
Konfiguracja
Sam wykonałem kilka testów i oto wyniki.
Utwórz tę procedurę:
create procedure dbo.Test
(
@Text1 varchar(10) = 'Default1'
,@Text2 varchar(10) = 'Default2'
)
as
begin
select @Text1 as Text1, @Text2 as Text2
end
Dodaj do niego ślad za pomocą programu SQL Server Profiler.
A następnie wywołaj go za pomocą następującego kodu:
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"]);
}
}
}
}
}
}
}
Wyniki
W obu przypadkach połączenia są wykonywane przy użyciu RPC.
Oto, co ujawnia ślad za pomocą CommandType.Text
:
exec sp_executesql N'dbo.Test',N'@Text1 nvarchar(5),@Text2 nvarchar(5)',@Text1=N'Text1',@Text2=N'Text2'
A oto wynik przy użyciu CommandType.StoredProcedure
:
exec dbo.Test @Text1=N'Text1',@Text2=N'Text2'
Jak widać, wywołanie tekstowe jest opakowane w wywołanie sp_executesql
aby był odpowiednio sparametryzowany. Spowoduje to oczywiście niewielkie obciążenie, a tym samym moje poprzednie stwierdzenie, że użycie CommandType.StoredProcedure
jest szybszy, nadal stoi.
Inną wartą uwagi rzeczą, która jest tutaj rodzajem łamania transakcji, jest to, że kiedy stworzyłem procedurę bez wartości domyślnych, otrzymałem następujący błąd:
Msg 201, Level 16, State 4, Procedure Test, Line 0 Procedura lub funkcja „Test” oczekuje parametru „@Text1”, którego nie podano.
Powodem tego jest to, jak wywołanie sp_executesql
jest tworzony, jak widać parametry są zadeklarowane i zainicjowane, ale nie są używane . Aby wywołanie zadziałało, powinno wyglądać tak:
exec sp_executesql N'dbo.Test @Text1, @Text2',N'@Text1 nvarchar(5),@Text2 nvarchar(5)',@Text1=N'Text1',@Text2=N'Text2'
To znaczy, gdy używasz CommandType.Text
musisz dodać parametry do CommandText
chyba że zawsze chcesz, aby były używane wartości domyślne.
A więc, aby odpowiedzieć na twoje pytanie
- Korzystanie z
CommandType.StoredProcedure
jest szybszy. - Jeśli używasz
CommandType.Text
, będziesz musiał dodać nazwy parametrów do wywołania procedury, chyba że chcesz użyć wartości domyślnych.