Answers:
打包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创建的。
如果这是.NET应用程序,则很可能是SqlCommand.ExecuteReader()被调用的结果。根据主要的SqlCommand类页面,在“备注”部分中方法描述的网格中,在ExecuteReader下显示:
执行返回行的命令。为了提高性能,ExecuteReader使用Transact-SQL sp_executesql系统存储过程来调用命令。因此,如果用于执行诸如Transact-SQL SET语句之类的命令,ExecuteReader可能不会具有您想要的效果。
我现在没有时间进行测试以确认其描述,但是创建一个简单的控制台应用程序应该足够容易,该应用程序可以进行非常简单的调用,传递一些查询文本,并包括随提供的参数SqlParameter
。我的猜测是ExecuteNonQuery
并且ExecuteScalar
还可以使用sp_executesql
它们,因为它们还允许传递参数,那么为什么会有不同的路径执行这些参数呢?