SQL不正确的 SQL 语法引起的异常

SQLException caused by incorrect SQL syntax

我有这段代码,它应该执行一个存储过程并return它的结果。

public static boolean finishOrderInteraction(int orderId, int departmentId){
        try{
            boolean result = true;
            Connection con = DriverManager.getConnection(SERVER, USER, PASSWORD);
            PreparedStatement stmt = con.prepareStatement("CALL finishOrderInteraction(?, ?, @result); SELECT @result AS Result;"); //returns true, if an SQLExeption accured during the procedure execution
            stmt.setInt(1, orderId);
            stmt.setInt(2, departmentId);
            ResultSet rs = stmt.executeQuery();
            while (rs.next()){
                result = rs.getBoolean("Result");
            }
            con.close();
            return !result;
        }catch (SQLException e){
            Logger.Severe("Failed to update order status", e, "-");
            return false;
        }
    }

我的问题是,这段代码产生了这个异常:

SQLException: (conn=122) You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'SELECT @result AS Result' at line 1

但是当我通过 MySql Workbench 尝试相同的查询时,一切都按预期工作。

MySql Workbench 查询:

CALL finishOrderInteraction(126, 1, @result); SELECT @result AS Result;

我就是想不通我做错了什么。为什么查询在 MySql Workbench 中有效,但在我的方法中无效?

您需要注册您的 OUT 参数,然后在对语句调用更新后访问这些值:

public static boolean finishOrderInteraction(int orderId, int departmentId) {
    Boolean result = true;

    try {
        Connection con = DriverManager.getConnection(SERVER, USER, PASSWORD);
        CallableStatement stmt = con.prepareCall("CALL finishOrderInteraction(?, ?, ?)");
        stmt.setInt(1, orderId);
        stmt.setInt(2, departmentId);
        stmt.registerOutParameter(3, java.sql.Types.BOOLEAN);

        stmt.executeUpdate();

        result = stmt.getBoolean(1);
        con.close();
    }
    catch (SQLException e) {
        Logger.Severe("Failed to update order status", e, "-");
        return false;
    }

    return result;
}

多亏了 Tim Biegeleisen 的 我才弄明白了。事实证明,这个异常有点误导,因为即使有语法错误,这个语法错误并不是我没有得到我想要的结果的原因。

真正的问题是我使用 con.prepareStatement(...) 而不是 con.prepareCall(...),因为 con.prepareCall(...) 创建了一个 CallableStatement 让你注册一个输出参数。多亏了这个参数,我的原始语句的第二个查询 SELECT @result AS Result; 才不再需要,这导致了语法错误。

我最终得到了这个工作代码:

public static boolean finishOrderInteraction(int orderId, int departmentId){
        try{
            Boolean result = true;
            Connection con = DriverManager.getConnection(SERVER, USER, PASSWORD);
            CallableStatement stmt = con.prepareCall("CALL finishOrderInteraction(?, ?, ?)");
            stmt.setInt(1, orderId);
            stmt.setInt(2, departmentId);
            stmt.registerOutParameter(3, Types.BOOLEAN);
            ResultSet rs = stmt.executeQuery();
            while (rs.next()){
                result = rs.getBoolean(1);
            }
            con.close();
            return result;
        }catch (SQLException e){
            Logger.Severe("Failed to finish order interaction.", e, "-");
            return false;
        }
    }