1

我有一个带有存储过程的 SQL Server 2000 数据库,它根据其 ID 从特定表中删除一行。当我从 VB.NET 调用存储过程时,它不会删除该行,而是通过 SSMS 直接在数据库上运行相同的脚本,它可以工作。

这是我的一系列事件:

  1. 启动 SQL Server Profiler 以监视对数据库的所有调用。我设置它来跟踪存储过程何时启动、完成,甚至在该存储过程中启动/完成 SQL 语句。
  2. 通过 VB.NET dll 调用存储过程。
  3. 停止探查器跟踪以避免挖掘过多的数据。
  4. 从表中选择,并查看该行仍然存在。
  5. 查看分析器跟踪,它只显示 RPC:Starting、SP:Starting、RPC:Completed。没有跟踪内部语句,这验证了为什么没有删除该行,因为删除语句从未触发。
  6. 直接从 RPC 复制/粘贴 EXEC 调用:从通过 VB.NET 调用它时开始的跟踪条目到 SQL Server Management Studio 查询窗口,该窗口指向具有相同凭据的相同数据库。
  7. 再次启动分析器。
  8. 执行 SSMS 中项目符号 6 中的 EXEC 语句。
  9. 停止探查器。
  10. 从表中选择,并看到该行 GOT DELETED 应该是这样。
  11. 查看分析器跟踪,其中显示 SP:Starting、所有开始/完成的语句(包括 DELETE 语句)和 SP:Completed。

为什么通过 RPC 运行它会使其不执行 proc 中的任何语句,而是直接运行它应该执行的操作?

编辑:下面是我的 VB.NET 代码。这是我们在其他 100 多个地方使用的相同代码:

Dim paramRowID As New SqlParameter("@RowID", sRowID) Microsoft.ApplicationBlocks.Data.SqlHelper.ExecuteNonQuery(oConn, "spDeleteRow", paramRowID)

请参阅此处的SqlHelper 源代码。

编辑:我现在讨厌自己。:) SQL 抛出异常“nvarchar 与图像不兼容”关于我传递 NULL 的另一个参数。SSMS 不担心类型,但 VB.NET 担心,因为我没有明确告诉它它是 image 类型。一旦我定义了那个参数,它就起作用了。我希望分析器会告诉我有一个错误。

任何帮助,将不胜感激,

格雷格

4

2 回答 2

4

那是因为 SSMS 不调用 RPC,而是调用批处理。事实上,没有办法从 SSMS 调用 RPC,因为您不能声明参数,这就是 RPC 调用与TDS中的批处理调用的区别:

2.2.1.3 SQL Batch发送一条SQL 语句或一批SQL 语句,将用Unicode 字符串表示的SQL 批处理复制到TDS 数据包的数据段,然后发送到支持SQL 的数据库服务器。一个 SQL 批处理可能跨越多个 TDS 数据包。有关详细信息,请参阅第 2.2.6.6 节

2.2.1.5 远程过程调用为了在服务器上执行远程过程调用(RPC),客户端向服务器发送一个RPC消息数据流。这是一个包含 RPC 名称或数字标识符、选项和参数的二进制流。RPC 必须在单独的 TDS 消息中,并且不能与 SQL 语句混合。一条消息中可以有多个 RPC。有关详细信息,请参阅第 2.2.6.5 节。

因此,请改为监视该SQL:BatchCompleted事件,您将看到您的 SSMS 语句。

于 2012-10-09T18:45:45.817 回答
0

应用程序用来连接 sql 的用户是否有权执行存储过程?这是我要验证的第一件事。

于 2012-10-09T18:41:52.910 回答