【问题标题】:Returning rowcount from CLR stored procedure从 CLR 存储过程返回行数
【发布时间】:2013-07-03 14:16:18
【问题描述】:

如果我有这样的存储过程:

CREATE PROCEDURE [dbo].[sp_update_dummy]
AS
BEGIN
  update update_dummy set value = value + 1 where id = 1
END

并使用executeUpdate(来自标准 java.sql 库)调用它,然后将更新的行数返回给 Java 程序(当然,假设更新语句更新了表中的一行)。

但是,如果我执行如下编码的 CLR 存储过程:

[Microsoft.SqlServer.Server.SqlProcedure]
public static void clr_update_dummy()
{
    using (SqlConnection conn = new SqlConnection("context connection=true"))
    {
        SqlCommand command = new SqlCommand("update update_dummy set value = value + 1 where id = 1", conn);

        conn.Open();

        command.ExecuteNonQuery();

        conn.Close();
    }
}

然后Java程序没有得到更新的行数(它似乎得到了一个返回值-1)。如果我将SET NOCOUNT ON 放入 SQL 存储过程中,也会发生这种情况。

所以在我看来,CLR 存储过程的行为就像使用了 SET NOCOUNT ON。

是否有任何方法可以编写 CLR 存储过程,以便可以像 SQL 存储过程一样获取行数?不幸的是,无法将 Java 程序(它是第 3 方组件)更改为例如获取 OUTPUT 参数。我看过 SqlContext.Pipe 但那里没有什么明显的。此外,我不确定将行计数返回给 executeUpdate 过程的机制。

我可能会创建一个 hack 来解决这个问题(例如,Java 执行一个 SQL 存储过程,而后者又执行一个 CLR 存储过程),但如果可能的话,我不想在调用堆栈中引入另一层。

【问题讨论】:

  • 附注:您不应该使用 sp_ 前缀作为存储过程名称 - 它是为 Microsoft 的系统过程保留的。
  • @Damien_The_Unbeliever - 我知道,我不明智地选择了这个名字。
  • 你需要使用CLR吗?这仅仅是为了避免使用 SQL 吗?
  • @gbn - 不幸的是它必须是 CLR。我宁愿使用 SQL,但我们正在构建一个复杂的外观以位于现有系统和多个数据库之间。 CLR 必须分解传入的请求,然后调用数据库上的存储过程。在完成概念验证后,我们认为 SQL 过于复杂。

标签: sql-server-2008-r2 clrstoredprocedure


【解决方案1】:

您可能(如果在 CLR 过程中转身并运行一段 SQL 有意义的话)想要调用 ExecuteAndSend

除了任何实际结果外,其他消息和错误也会直接发送到客户端。

SqlCommand command = new SqlCommand("update update_dummy set value = value + 1 where id = 1", conn);
conn.Open();

SqlContext.Pipe.ExecuteAndSend(command);

【讨论】:

  • 谢谢,这可以正常工作,但前提是我使用 SqlCommand。对于某些数据库,我必须使用 SqlContext.Pipe 不接受的 OdbcCommand。有没有办法可以看到 ExecuteAndSend 放入管道的内容?也许如果我调用 ExecuteReader 然后通过结果集我会得到一些想法......
  • 用 ExecuteReader 替换 ExecuteNonQuery 并查看返回的 SqlDataReader 我可以看到一个 RecordsAffected 整数,它告诉我更新影响了多少行。但是,我不确定如何在不使用 Pipe.ExecuteAndSend 方法的情况下将此信息返回给调用者。
  • @KeithMiller - 我快速浏览了SqlPipe 类,那里似乎没有任何可能的方法。我能想到的只是一个丑陋的博格——手头有行数信息,构造一个影响相同行数的 SQL 查询并执行它。
  • 我认为这可能是要走的路。这很可怕,但如果它完成了工作,那将是值得的。我会在这里发布我的结果。
  • 我接受了@Damien_The_Unbeliever 的建议,现在有了一个 SQL 存储过程,它执行我的 CLR 代码,然后更新一个虚拟表。
猜你喜欢
  • 2013-06-21
  • 1970-01-01
  • 2013-04-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多