可以默认配置/使用 sp_executesql 吗?

Mag*_*ier 11 sql-server-2008 sql-server dynamic-sql

我正在查看一个对 SQL Server 使用高度动态 sql 查询的应用程序。查看以非常奇怪和复杂的方式构建的查询,但这是一个不同的故事,我告诉它是为了给我无法(太愚蠢)自己找出问题的充分理由......我看不到查询用sp_executesql.

但是当我跟踪时,我可以看到很多查询都包含在sp_executesql. 整个应用程序解决方案甚至根本不包含该命令sp_executesql

所以我想知道是否有一种我还不知道的配置强制软件默认使用 sp_executesql 包装查询?

什么可能导致这种行为?

Mag*_*ier 12

SQL 语句被包装的原因sp_executesqlSqlCommand.Commandtype属性的设置并将任何参数传递给命令。

SqlCommand cmd = new SqlCommand("proc1", con);
cmd.CommandType = CommandType.StoredProcedure;                
cmd.Parameters.AddWithValue("@param1", 1);
con.Open();
cmd.ExecuteNonQuery();
con.Close();
Run Code Online (Sandbox Code Playgroud)

上面的代码以这个 T-SQL 结尾:

exec proc1 @param1=1
Run Code Online (Sandbox Code Playgroud)
exec proc1 @param1=1
Run Code Online (Sandbox Code Playgroud)

此代码以执行以下 T-SQL 结束:

exec sp_executesql N'proc1',N'@param1 int',@param1=1
Run Code Online (Sandbox Code Playgroud)

补充 23.12.15:使用CommandType.Text命令,结果是相似的:只要将参数添加到命令对象中,.NET 就会将整个查询包装到其中sp_executesql并将参数传递给它。

另外:在深入研究之后sp_executesql,参数嗅探和计划缓存 .NET 类的这种行为完全有意义,以避免高频率查询编译和计划数量。因此,它基本上旨在确保总体上更好的 SQL Server 性能,同时可能导致某些查询(参数嗅探问题)的性能不佳,这些查询使用与初始创建的查询计划不同的参数值。

看:

上述示例是使用 .NET Framework 4.5 和 SQL Server 2008 Developer Edition 创建的。


Sol*_*zky 5

如果这是一个 .NET 应用程序,则很可能是调用了SqlCommand.ExecuteReader()的结果。根据主SqlCommand类页面,在“备注”部分的方法描述网格中,在ExecuteReader下,它说:

执行返回行的命令。为了提高性能,ExecuteReader 使用 Transact-SQL sp_executesql系统存储过程调用命令。因此,如果用于执行 Transact-SQL SET 语句等命令,ExecuteReader 可能不会达到您想要的效果。

我现在没有时间对此进行测试以确认他们的描述,但是创建一个简单的控制台应用程序应该很容易,该应用程序执行非常简单的调用,传入一些查询文本,并包含一个随SqlParameter. 我的猜测是,ExecuteNonQueryExecuteScalar也使用sp_executesql,因为它们还允许传入的参数,那么,为什么会有如何的执行不同的路径?