Според тестовете в тази публикация в блога SQL Server ще направи параметризацията вместо вас, като обвие вашето изявление в sp_executesql, когато използвате CommandType.Text
. Но когато използвате CommandType.StoredProcedure
ще го параметризирате и по този начин ще спестите на базата данни известна работа. Последният метод е по-бърз.
Редактиране:
Настройка
Аз лично направих някои тестове и ето резултатите.
Създайте тази процедура:
create procedure dbo.Test
(
@Text1 varchar(10) = 'Default1'
,@Text2 varchar(10) = 'Default2'
)
as
begin
select @Text1 as Text1, @Text2 as Text2
end
Добавете следа към него с помощта на SQL Server Profiler.
След това го извикайте, като използвате следния код:
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"]);
}
}
}
}
}
}
}
Резултати
И в двата случая повикванията се извършват чрез RPC.
Ето какво разкрива проследяването с помощта на CommandType.Text
:
exec sp_executesql N'dbo.Test',N'@Text1 nvarchar(5),@Text2 nvarchar(5)',@Text1=N'Text1',@Text2=N'Text2'
И ето резултата с помощта на CommandType.StoredProcedure
:
exec dbo.Test @Text1=N'Text1',@Text2=N'Text2'
Както можете да видите, текстовото повикване е обвито в извикване към sp_executesql
така че да е правилно параметризиран. Това, разбира се, ще създаде леки допълнителни разходи и по този начин предишното ми изявление, че използвам CommandType.StoredProcedure
е по-бързо все още стои.
Друго забележително нещо, което също е нещо като прекъсване на сделката тук, е, че когато създадох процедурата без стойности по подразбиране, получих следната грешка:
Съобщение 201, ниво 16, състояние 4, тест на процедурата, ред 0 Процедура или функция „Тест“ очаква параметър „@Text1“, който не е предоставен.
Причината за това е как извикването на sp_executesql
се създава, както можете да видите, параметрите са декларирани и инициализирани, но не се използват . За да работи обаждането, трябваше да изглежда така:
exec sp_executesql N'dbo.Test @Text1, @Text2',N'@Text1 nvarchar(5),@Text2 nvarchar(5)',@Text1=N'Text1',@Text2=N'Text2'
Това означава, че когато използвате CommandType.Text
трябва да добавите параметрите към CommandText
освен ако не искате винаги да се използват стойностите по подразбиране.
И така, за да отговоря на въпроса ви
- Използване на
CommandType.StoredProcedure
е по-бързо. - Ако използвате
CommandType.Text
, тогава ще трябва да добавите имената на параметрите към извикването към процедурата, освен ако не искате да се използват стойностите по подразбиране.