4

这个 MySql 错误消息是什么意思?

java.sql.SQLException: boo!

springframework.dao.TransientDataAccessResourceException: CallableStatementCallback; SQL [{call sp_MyStoredProc(?, ?, ?)}]; boo!

可以肯定的是,这并不是特别有意义。有没有人遇到过这个并且能够翻译成不那么懒惰〜开发者〜ish ...?

我正在通过org.springframework.jdbc.object.StoredProcedure

我在用org.springframework.jdbc-3.1.3

@更新

违规行位于 CallableStatetement.java (2269-2271)

if (!found) {
     throw SQLError.createSQLException("boo!", "S1000", this.connection.getExceptionInterceptor());`
}

附加 mysql-connector-java-5.1.18.jar 的源代码并跟踪代码,发现正确的消息应该是“声明参数和实际参数之间不匹配”或类似的行。

确实正确地声明了我的输出参数

declareParameter(new SqlOutParameter("output", Types.INTEGER));

而不是

declareParameter(new SqlParameter("output", Types.INTEGER));

解决了我的问题。但是更有意义的错误消息会节省宝贵的时间。我将向 MySql Connector/J 开发团队提出这个建议。

4

1 回答 1

3

As stated in the update to the question this is commonly caused by incorrectly using a CallableStatement. For example:

Stored Procedure uses 2 parameters, one in and one out:

CREATE DEFINER=`example`@`localhost` PROCEDURE `sp_getSensorLocation`(IN in_id VARCHAR(128), OUT loc VARCHAR(128))
BEGIN
SELECT LOCATION INTO loc FROM table.SENSORS
WHERE ID = in_id;
END

but the call to it only uses 1:

private String getSensorLocation(String sensorID) {    
    String location = "";
    Connection c = dbr.getConnection();
    String prepStatement = "{ call sp_getSensorLocation(?) } ";
    try {
         callableStatement cs = c.prepareCall(prepStatement);
         cs.setString(1, sensorID);
         ResultSet rs = cs.executeQuery();
         if (rs.next()) {
            location = rs.getString(1);
            }
         } catch (SQLException ex) {
                LOG.error("Error:", ex);
         }        
    dbr.closeConnection(c, rs, cs);
    return location;
}

When the correct code is really:

private String getSensorLocation(String sensorID) {
    String location = "";
    Connection c = dbr.getConnection();
    String prepStatement = "{ call sp_getSensorLocation(?, ?) } ";
    try {
        CallableStatement cs = c.prepareCall(prepStatement);
        cs.setString(1, sensorID);
        cs.execute();
        location = cs.getString(2);            
    } catch (SQLException ex) {
        LOG.error("Error:", ex);
    }
    dbr.closeConnection(c, rs, cs);
    return location;
}

Notice I also changed to cs.execute as I don't expect a result set and would have issues with this as well (the example is taken from someone else's code I'm fixing, the joys -_-)

于 2013-07-04T14:21:29.460 回答