【问题标题】:Stored Procedure exceptions not being detected by JDBCJDBC 未检测到存储过程异常
【发布时间】:2021-07-12 21:25:09
【问题描述】:

我正在使用准备好的语句 jdbc 模板运行存储过程:

conn = dbrm.getConnection(this.dataSources.get(aas.getArgumentValue("dataSource")));
Statement stmt = conn.createStatement();
try{
    boolean hasResultSet = stmt.execute(query);
catch(Exception e){
    // log and handle appropriately
}

我的存储过程基本上是一个存储过程调用另外两个存储过程。

我遇到的问题是,如果在存储过程的第一条语句之后出现异常,那么异常不会返回到 jdbc 模板,所以看起来我的存储过程对我的 java 代码有效,即使它没有,这显然是有问题的。

有没有办法手动检查存储过程的输出或让所有可能的异常冒泡到 java?

【问题讨论】:

    标签: java sql-server stored-procedures jdbc


    【解决方案1】:

    似乎在执行存储过程时,引发的异常可能会在成功结果后面“排队”。为了“检索”异常,我们可能必须使用CallableStatement 对象的getMoreResults 方法。

    例如,给定存储过程

    CREATE PROCEDURE [dbo].[Table1sp] AS
    BEGIN
        SET NOCOUNT ON;
        SELECT 123;
        CREATE TABLE #Table1 (textcol VARCHAR(50) PRIMARY KEY);
        INSERT INTO #Table1 (textcol) VALUES (NULL);  -- error here
    END
    

    如果我们运行 Java 代码

    String connectionUrl = "jdbc:sqlserver://localhost:52865;"
            + "databaseName=myDb;" + "integratedSecurity=true";
    try (Connection conn = DriverManager.getConnection(connectionUrl)) {
        try (CallableStatement cs = conn.prepareCall("{call Table1sp}")) {
            cs.execute();
            ResultSet rs = cs.getResultSet();
            rs.next();
            System.out.println(rs.getInt(1));
            rs.close();
        }
    } catch (Exception e) {
        e.printStackTrace(System.err);
    }
    

    然后我们只打印值123 并且我们的代码继续运行,就好像没有任何问题一样。

    但是,如果我们跟进getMoreResults() 电话...

    String connectionUrl = "jdbc:sqlserver://localhost:52865;"
            + "databaseName=myDb;" + "integratedSecurity=true";
    try (Connection conn = DriverManager.getConnection(connectionUrl)) {
        try (CallableStatement cs = conn.prepareCall("{call Table1sp}")) {
            cs.execute();
            ResultSet rs = cs.getResultSet();
            rs.next();
            System.out.println(rs.getInt(1));
            rs.close();
    
            try {
                cs.getMoreResults();
            } catch (com.microsoft.sqlserver.jdbc.SQLServerException ex) {
                System.out.println("SQLServerException: " + ex.getMessage());
            }
    
        }
    } catch (Exception e) {
        e.printStackTrace(System.err);
    }
    

    ...然后异常被捕获:

    123
    SQLServerException: Cannot insert the value NULL into column 'textcol', table 'tempdb.dbo.#Table1 ...
    

    【讨论】:

    • 很好的答案,在 getMoreResults 中,异常是文本还是可抛出的?
    • 这是一个真实的com.microsoft.sqlserver.jdbc.SQLServerException,由getMoreResults 调用本身抛出。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-07-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多