Причиной переноса операторов SQL sp_executesql
является установка SqlCommand.Commandtype
свойства и передача в команду любых параметров.
SqlCommand cmd = new SqlCommand("proc1", con);
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.AddWithValue("@param1", 1);
con.Open();
cmd.ExecuteNonQuery();
con.Close();
Код выше заканчивается этим T-SQL:
exec proc1 @param1=1
SqlCommand cmd = new SqlCommand("proc1", con);
cmd.CommandType = CommandType.Text;
cmd.Parameters.AddWithValue("@param1", 1);
con.Open();
cmd.ExecuteNonQuery();
con.Close();
Этот код заканчивается выполнением следующего T-SQL:
exec sp_executesql N'proc1',N'@param1 int',@param1=1
Дополнение 23.12.15: Использование CommandType.Text
команды приводит к аналогичным результатам: как только параметр добавляется в объект команды, .NET обернет весь запрос sp_executesql
и передаст ему параметры.
Дополнение. После более глубокого погружения в sp_executesql
анализ параметров и кэширования планов такое поведение классов .NET полностью приобретает смысл во избежание частой компиляции запросов и количества планов. Таким образом, он в основном предназначен для обеспечения большей производительности SQL Server в целом, в то же время он может привести к низкой производительности некоторых запросов (проблема с анализом параметров), которые используются с значениями параметров, отличными от первоначально созданного плана запроса.
Увидеть:
Приведенный выше пример был создан с использованием .NET Framework 4.5 и SQL Server 2008 Developer Edition.