Message d'erreur MySQL Connector/J obscur-java.SQL.SQLException: boo {point d'exclamation}


Que signifie ce message d'erreur MySQL?

java.sql.SQLException: boo!

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

Ce n'est pas particulièrement significatif, c'est sûr. Quelqu'un a-t-il rencontré cela et est capable de traduire en moins paresseux~developer~ish...?

J'accède via org.springframework.jdbc.object.StoredProcedure

J'utilise org.springframework.jdbc-3.1.3

@ Mise à jour

Les lignes incriminées sont dans CallableStatetement.java (2269-2271)

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

Attching les sources pour mysql-connector-java-5.1.18.jar et traçage bien que le code révèle que le bon le message doit être du type "discordance entre les paramètres déclarés et réels" ou similaire.

En effet déclarer correctement mon paramètre de sortie

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

Plutôt que

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

Correction de mon problème. Mais un message d'erreur plus significatif aurait permis de gagner un temps précieux. Je vais faire cette suggestion à l'équipe de développement MySQL Connector/J.

Author: eddyoc, 2013-05-29

1 answers

Comme indiqué dans la mise à jour de la question, cela est généralement causé par une utilisation incorrecte d'un CallableStatement. Par exemple:

La procédure stockée utilise 2 paramètres, un in et un 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

Mais l'appel n'utilise que 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;
}

Quand le code correct est vraiment:

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;
}

Notez que j'ai également changé en cs.exécuter car je ne m'attends pas à un jeu de résultats et aurait également des problèmes avec cela (l'exemple est tiré du code de quelqu'un d'autre que je corrige, les joies -_ -)

 3
Author: RyanfaeScotland, 2013-07-04 14:54:18