2015-08-27 2 views
4

J'utilise jdbc CallableStatement pour exécuter des procédures dans la base de données MySQL. Lors de l'écriture de tests unitaires, j'ai rencontré un comportement étrange concernant la méthode registerOutParameter.Quelle est la signification de sqlType dans registerOutParameter de jdbc?

procédures SQL utilisées

PROCEDURE TEST_DOUBLE(OUT val DOUBLE) BEGIN SET val = 2.5; END 
PROCEDURE TEST_TEXT(OUT val TEXT) BEGIN SET val = 'test'; END 

Tests

statement = connection.prepareCall("CALL TEST_DOUBLE(?)"); 
statement.registerOutParameter("val" , java.sql.Types.INTEGER); 
statement.execute(); 
statement.getInt("val"); //Integer 2 
statement.getDouble("val"); //Double 2.5 
statement.getString("val"); //String "2.5" 

statement = connection.prepareCall("CALL TEST_TEXT(?)"); 
statement.registerOutParameter("val" , java.sql.Types.INTEGER); 
statement.execute(); 
statement.getInt("val"); //Invalid value for getInt 
statement.getDouble("val"); //Invalid value for getDouble 
statement.getString("val"); //String "test" 

statement = connection.prepareCall("CALL TEST_TEXT(?)"); 
statement.registerOutParameter("val" , 0); 
statement.execute(); 
statement.getInt("val"); //Invalid value for getInt 
statement.getDouble("val"); //Invalid value for getDouble 
statement.getString("val"); //String "test" 

et ainsi de suite ...

Mon point est -. Les valeurs java.sql.Types * transmises à registerOutParameter semblent faire rien ... Quel que soit le type sql que je passe, tout dépend de l'appel de la méthode getter et de la valeur réelle retournée par la base de données.

Puis-je passer partout 0 et cela fonctionnera correctement? Pourquoi ce paramètre est-il passé? Ou peut-être est-ce lié à la base de données, et pour d'autres bases de données c'est important?

Répondre

0

Je suppose que ce paramètre est lié à la base de données. Oracle y prête certainement attention:

statement = connection.prepareCall("CALL_TEST_NUMBER(?)"); 
statement.registerOutParameter("val", java.sql.Types.INTEGER); 
statement.execute(); 
statement.getInt("val");  // 2 
statement.getDouble("val"); // 2.5 
statement.getString("val"); // "2.5" 

statement = connection.prepareCall("CALL TEST_TEXT(?)"); 
statement.registerOutParameter("val", java.sql.Types.INTEGER); 
statement.execute(); // java.sql.SQLSyntaxErrorException: ORA-01722: invalid number 
0

Cette méthode attend un nombre entier dans ce pararamètre comme vous pouvez le voir dans jdbc documentation. Le champ que vous utilisez comme une constante (java.sql.Types.INTEGER) est un int (public statique final int INTEGER) comme tout le reste des valeurs constantes dans java.sql.Types, et c'est pourquoi votre code fonctionne lorsque vous mettez 0 (peut-être 0 valeur est le même que java.sql.Types.INTEGER ou un autre type de numéro). Ce paramètre indique au pilote le type que vous prévoyez de lire pour cette valeur de sortie. Lorsque vous essayez d'utiliser un autre java.sql.Type (java.sql.Type.ARRAY), vous obtenez probablement une erreur classCast ou de conversion car le pilote jdbc ne sait pas comment convertir la valeur renvoyée par de callableStatement (un nombre) au type que vous vouliez (un tableau).

+0

Je viens de tester cela, et il s'est avéré que ce n'était pas vrai. La procédure a OUT val INT J'ai utilisé registerOutParam ("val", java.sql.Types.ARRAY) Si seulement j'utilise le code getInt ("val") fonctionne sans aucun problème, comme si je passais java.sql. Types.INTEGER ou 0 – piotrgajow

+1

Um, c'est bizarre. Le comportement de cette méthode devrait être ce qui est décrit dans l'API jdbc, comme cela est expliqué dans la documentation. Peut-être que le pilote que vous utilisez a un comportement différent? Avez-vous javadoc API spécifique au pilote soma? –