Ответ 1
В соответствии с тестами в этот пост в блоге 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
быстрее, остается.
Еще одна заслуживающая внимания вещь, которая также является видом прерывателя сделки, заключается в том, что когда я создал процедуру без значений по умолчанию, я получил следующую ошибку:
Msg 201, уровень 16, состояние 4, проверка процедуры, строка 0 Процедура или функция 'Test' ожидает параметр '@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
, вам придется добавить имена параметров к вызову процедуры, если вы не хотите использовать значения по умолчанию.