【问题标题】:Raise Java SQLException from SQL Server stored procedure?从 SQL Server 存储过程中引发 Java SQLException?
【发布时间】:2020-07-14 03:42:39
【问题描述】:

我有一个类似这样的 SQL Server 存储过程:

CREATE PROCEDURE proc1
(
    @param DECIMAL
)
AS
    BEGIN
        INSERT INTO table1 (@param);
        -- further commands
    END;
GO

此过程是从 Java 调用的。我在上面插入的同一列上引入了对table1 的唯一约束。如果发生约束冲突,预计会在 Java 中获得 SQLException,但它没有发生。当从 SSMS 手动执行该过程时,我可以看到它打印出违反约束的错误,然后继续该过程的其余部分,我认为这很奇怪,我预计它会失败。所以我改成这样:

CREATE PROCEDURE proc1
(
    @param DECIMAL
)
AS
    BEGIN
        BEGIN TRY
            INSERT INTO table1 (@param);
        END TRY
        BEGIN CATCH
            THROW 51000, 'Unable to insert', 1;
        END CATCH
        -- further commands
    END;
GO

现在,当我在 SSMS 中手动执行它时,该过程会在出现故障时停止,并打印我的错误消息。但是,Java 调用进程没有收到任何错误指示。如何将此错误传播到 Java 调用层?

更新:Java 调用层:

Class.forName("com.microsoft.sqlserver.jdbc.SQLServerDriver");
String connectionUrl = "jdbc:sqlserver://x.x.x.x;database=x";

try (Connection conn = DriverManager.getConnection(connectionUrl, "x", "x")) {
    try (CallableStatement stmt = conn.prepareCall("{call proc1(?)}")) {
        stmt.setInt(1, 1);

        stmt.execute();

        System.out.println("Done");
    }
}

最后,我可以看到控制台打印出“完成”消息。

【问题讨论】:

  • 这里我只使用THROW,而不是THROW 51000, 'Unable to insert', 1;,否则你会隐藏错误,这使得以后的任何调试都非常困难。
  • 你说得对,它使调试更容易,我们可以看到确切的 SQL 错误。然而,Java 调用层仍然没有收到错误通知。它执行存储过程,并正常继续。我用 Java 代码更新了我的问题。

标签: java sql-server stored-procedures


【解决方案1】:

添加 SET NOCOUNT ON 作为 proc 中的第一条语句以抑制 DONE_IN_PROC(行数)TDS 消息。否则,代码将需要使用ResultSetgetMoreResults 返回的所有结果,然后才会在客户端引发错误。

【讨论】:

  • 是的!谢谢你。我读到了这个 NOCOUNT 标志,但我把它添加到错误的地方,在 SP 本身之前。现在它工作正常。谢谢!
  • @GáborMajor,很高兴它有帮助。另请参阅The Curious Case of Undetected SQL Exceptions 了解其他注意事项。
猜你喜欢
  • 1970-01-01
  • 2018-03-20
  • 2011-11-07
  • 2016-02-15
  • 1970-01-01
  • 1970-01-01
  • 2012-02-10
  • 2020-06-06
  • 1970-01-01
相关资源
最近更新 更多