Согласно тестам в в этом блоге SQL Server выполнит параметризацию за вас, обернув ваше утверждение в sp_executesql, когда вы используете CommandType.Text
. Но когда вы используете CommandType.StoredProcedure
, вы его параметризуете и тем самым сохраняете базу данных некоторую работу. Последний способ быстрее.
Edit:
Настройка
Я сам провел несколько тестов, и вот результаты.
Создать эту процедуру:
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
, вам придется добавить имена параметров к вызову процедуры, если вы не хотите использовать значения по умолчанию.