为什么我的数据库命令总是调用 sp_describe_first_result_set?
Why are my database Commands always calling sp_describe_first_result_set?
背景
我正在维护一个 VB.Net(以前称为 VB6)实用程序,可将记录导出到平面文件。我们的一位客户报告说新版本 运行 花费了很长时间,并且深入研究跟踪很容易看出原因:(我稍微混淆了这一点)
exec [sys].sp_describe_first_result_set
N'Update [MAIN].[dbo].[Inventory] Set ExportId = @P1 Where Comp = @P2 and Osite = @P3 and Key = @P4',
N'@P1 numeric(10),@P2 varchar(6),@P3 varchar(6),@P4 int',1
这个和类似的语句每个都需要半秒钟。该实用程序必须使用有关导出的一些信息更新主清单 table,并且 table 被严重触发,因此 sp_describe_first_result_set
必须模拟所有触发器以确定结果 -我可以稍后在跟踪中验证这一点。
问题
我不明白为什么我的代码会调用 sp_describe_first_result_set
更新语句,甚至没有结果集。命令设置看起来没有做任何奇怪的事情:
Dim connection = New ADODB.Connection
connection.ConnectionString = config.AdoConnectionString
connection.CursorLocation = CursorLocationEnum.adUseClient
connection.Open()
cmd = New ADODB.Command
With cmd
.ActiveConnection = connection
.CommandType = CommandTypeEnum.adCmdText
.CommandText = "Update [MAIN].[dbo].[Inventory] " &
"Set ExportId = ? " &
"Where Comp = ? and Osite = ? and Key = ?"
.Parameters.Append(NumericParameter(cmd.CreateParameter("ExportId", DataTypeEnum.adNumeric, ParameterDirectionEnum.adParamInput), 10, 0))
.Parameters.Append(cmd.CreateParameter("Comp", DataTypeEnum.adVarChar, ParameterDirectionEnum.adParamInput, 6))
.Parameters.Append(cmd.CreateParameter("Osite", DataTypeEnum.adVarChar, ParameterDirectionEnum.adParamInput, 6))
.Parameters.Append(cmd.CreateParameter("Key", DataTypeEnum.adInteger, ParameterDirectionEnum.adParamInput))
End With
cmd.Parameters("ExportID").Value = lExportId
cmd.Parameters("Comp").Value = sComp
cmd.Parameters("Osite").Value = sOsite
cmd.Parameters("Key").Value = iKey
cmd.Execute()
是否有一些我一直缺少的设置一直 运行 sp_describe_first_result_set
?有没有办法阻止它这样做?
出于好奇,与该代码等效的现代代码是否也跟踪执行此操作?
Dim cmd as New SqlCommand( _
"Update [MAIN].[dbo].[Inventory] Set ExportId = @e Where Comp = @c and Osite = @o and Key = @k",
"Data Source=YOUR_SERVER;Initial Catalog=YOUR_DB;User ID=YOUR_USER_EG_sa;Password=YOUR_PASSWORD" _
)
cmd.Connection.Open()
cmd.Parameters.AddWithValue("@e", lExportId)
cmd.Parameters.AddWithValue("@c", sComp)
cmd.Parameters.AddWithValue("@o", sOsite)
cmd.Parameters.AddWithValue("@k", iKey)
cmd.ExecuteNonQuery()
我在这里使用 AddWithValue 是为了 testing/convenience 目的,但您可能应该在产品中避免使用它 because it can cause performance issues with SQLS - 请参阅 link 以获取有关如何正确制作参数的建议
您需要明确说明您不需要记录集。
在 VB6 中,ADODB 命令对象可以根据 Execute()
函数的值是否被分配给任何东西来判断它是否应该 return 一个记录集。
在 VB.NET 中不再这样做,但是 execution options flags 可以作为参数提供给 Execute()
函数。像这样调用命令:
cmd.Parameters("ExportID").Value = lExportId
cmd.Parameters("Comp").Value = sComp
cmd.Parameters("Osite").Value = sOsite
cmd.Parameters("Key").Value = iKey
cmd.Execute(Options:=ExecuteOptionEnum.adExecuteNoRecords)
不会调用sp_describe_first_result_set
建立记录集的参数,只会直接执行命令,同理更现代的方法如SqlCommand.ExecuteNonQuery()
也会。
背景
我正在维护一个 VB.Net(以前称为 VB6)实用程序,可将记录导出到平面文件。我们的一位客户报告说新版本 运行 花费了很长时间,并且深入研究跟踪很容易看出原因:(我稍微混淆了这一点)
exec [sys].sp_describe_first_result_set
N'Update [MAIN].[dbo].[Inventory] Set ExportId = @P1 Where Comp = @P2 and Osite = @P3 and Key = @P4',
N'@P1 numeric(10),@P2 varchar(6),@P3 varchar(6),@P4 int',1
这个和类似的语句每个都需要半秒钟。该实用程序必须使用有关导出的一些信息更新主清单 table,并且 table 被严重触发,因此 sp_describe_first_result_set
必须模拟所有触发器以确定结果 -我可以稍后在跟踪中验证这一点。
问题
我不明白为什么我的代码会调用 sp_describe_first_result_set
更新语句,甚至没有结果集。命令设置看起来没有做任何奇怪的事情:
Dim connection = New ADODB.Connection
connection.ConnectionString = config.AdoConnectionString
connection.CursorLocation = CursorLocationEnum.adUseClient
connection.Open()
cmd = New ADODB.Command
With cmd
.ActiveConnection = connection
.CommandType = CommandTypeEnum.adCmdText
.CommandText = "Update [MAIN].[dbo].[Inventory] " &
"Set ExportId = ? " &
"Where Comp = ? and Osite = ? and Key = ?"
.Parameters.Append(NumericParameter(cmd.CreateParameter("ExportId", DataTypeEnum.adNumeric, ParameterDirectionEnum.adParamInput), 10, 0))
.Parameters.Append(cmd.CreateParameter("Comp", DataTypeEnum.adVarChar, ParameterDirectionEnum.adParamInput, 6))
.Parameters.Append(cmd.CreateParameter("Osite", DataTypeEnum.adVarChar, ParameterDirectionEnum.adParamInput, 6))
.Parameters.Append(cmd.CreateParameter("Key", DataTypeEnum.adInteger, ParameterDirectionEnum.adParamInput))
End With
cmd.Parameters("ExportID").Value = lExportId
cmd.Parameters("Comp").Value = sComp
cmd.Parameters("Osite").Value = sOsite
cmd.Parameters("Key").Value = iKey
cmd.Execute()
是否有一些我一直缺少的设置一直 运行 sp_describe_first_result_set
?有没有办法阻止它这样做?
出于好奇,与该代码等效的现代代码是否也跟踪执行此操作?
Dim cmd as New SqlCommand( _
"Update [MAIN].[dbo].[Inventory] Set ExportId = @e Where Comp = @c and Osite = @o and Key = @k",
"Data Source=YOUR_SERVER;Initial Catalog=YOUR_DB;User ID=YOUR_USER_EG_sa;Password=YOUR_PASSWORD" _
)
cmd.Connection.Open()
cmd.Parameters.AddWithValue("@e", lExportId)
cmd.Parameters.AddWithValue("@c", sComp)
cmd.Parameters.AddWithValue("@o", sOsite)
cmd.Parameters.AddWithValue("@k", iKey)
cmd.ExecuteNonQuery()
我在这里使用 AddWithValue 是为了 testing/convenience 目的,但您可能应该在产品中避免使用它 because it can cause performance issues with SQLS - 请参阅 link 以获取有关如何正确制作参数的建议
您需要明确说明您不需要记录集。
在 VB6 中,ADODB 命令对象可以根据 Execute()
函数的值是否被分配给任何东西来判断它是否应该 return 一个记录集。
在 VB.NET 中不再这样做,但是 execution options flags 可以作为参数提供给 Execute()
函数。像这样调用命令:
cmd.Parameters("ExportID").Value = lExportId
cmd.Parameters("Comp").Value = sComp
cmd.Parameters("Osite").Value = sOsite
cmd.Parameters("Key").Value = iKey
cmd.Execute(Options:=ExecuteOptionEnum.adExecuteNoRecords)
不会调用sp_describe_first_result_set
建立记录集的参数,只会直接执行命令,同理更现代的方法如SqlCommand.ExecuteNonQuery()
也会。