2009-03-13 9 views
1

J'utilise spring-2.5.6 pour me connecter à partir d'une application autonome à une base de données Oracle 10g (ojdbc14.jar) en utilisant le fichier org.apache.commons.dbcp.BasicDataSource. Lorsque j'essaie de récupérer un SqlRowSet à l'aide de la méthode public SqlRowSet queryForRowSet(String sql, Object[] args) throws DataAccessException, j'obtiens une java.sql.SQLException: taille d'échelle non valide. Ne peut pas être inférieur à zéro.Taille d'échelle non valide. Ne peut pas être inférieur à

Le sql appelant la table est:

select CUSTAREADESC, BEGCOL, COLLENGTH from CUSTOMERAREA where upper(trim(FLEET)) = upper(trim(?)) and CUSTAREANO = ? 

Les colonnes BEGCOL et COLLENGTH sont du nombre de type de données sans précision définie.

J'ai trouvé quelques informations sur ce problème, semble être une incompatibilité entre les pilotes Oracle et l'implémentation de com.sun.rowset.CachedRowSetImpl de Sun.

Java Database Connectivity (JDBC) - Populating CachedRowSet produces SQLException: Invalid scale size

Using queryForRowSet with subquery factoring SQL gives errors

Ils suggèrent de changer le sql à ce qui suit comme un travail autour.

select CUSTAREADESC, (BEGCOL + 0) BEGCOL, (COLLENGTH + 0) COLLENGTH from CUSTOMERAREA where upper(trim(FLEET)) = upper(trim(?)) and CUSTAREANO = ? 

Est-ce que quelqu'un sait d'une meilleure solution générique qui n'implique pas sql personnalisé pour une table existante où une colonne ne dispose pas de précision définie?

Répondre

1

J'ai fini par créer une classe ResultSetExctractor qui implémente ResultSetExtractor et utilisée pour obtenir une implémentation OracleCachedRowSet de SqlRowSet. Pour l'utiliser, vous devrez inclure le fichier du pilote Oracle dans votre projet (utilisé ojdbc14.jar).

public class SqlRowSetOracleResultSetExtractor implements ResultSetExtractor { 

    public Object extractData(ResultSet rs) throws SQLException { 
     return createSqlRowSet(rs); 
    } 

    protected SqlRowSet createSqlRowSet(ResultSet rs) throws SQLException { 
     CachedRowSet rowSet = newCachedRowSet(); 
     rowSet.populate(rs); 
     return new ResultSetWrappingSqlRowSet(rowSet); 
    } 

    protected CachedRowSet newCachedRowSet() throws SQLException { 
     return new OracleCachedRowSet(); 
    } 
} 

Ceci est ensuite utilisé de la manière suivante pour extraire un SqlRowSet.

SqlRowSet rs = (SqlRowSet) this.jdbcTemplate.query(SELECT_CUSTOMER_AREA, 
       new Object[]{new SqlParameterValue(Types.VARCHAR, companyId), 
       new SqlParameterValue(Types.NUMERIC, areaNumber)}, 
       new SqlRowSetOracleResultSetExtractor()); 
0

Quel Oracle Jar utilisez-vous? Essayez de mettre à niveau vers le plus récent (en supposant que vous utilisez JDK 5 ou supérieur). Je crois que le dernier fichier ojdbc5.jar [ou ojdbc6.jar] a corrigé ce problème - il était dû au fait que les pilotes Oracle ne prenaient pas correctement en charge l'interface CachedRowSet.

Lien de téléchargement: Oracle JDBC Drivers

+0

Limité à Oracle 10g – Rob

+0

Ces fichiers JAR fonctionnent correctement avec 10g. – Gandalf

0

Essayez cette requête:

select NVL(CUSTAREADESC, '0'), (NVL(BEGCOL,0) + 0) BEGCOL, (NVL(COLLENGTH, 0) + 0) COLLENGTH 
from CUSTOMERAREA 
where NVL(upper(trim(NVL(FLEET, ''))), '') = NVL(upper(trim(NVL(?, ''))), '') 
    and NVL(CUSTAREANO, '0') = NVL(?, '') 

est l'exception SQL toujours en cours?

2

Cette erreur est due à une incompatibilité dans les pilotes Oracle JDBC. Vous pouvez le résoudre en définissant la propriété système oracle.jdbc.J2EE13Compliant sur true. Par exemple, sur la ligne de commande:

java -Doracle.jdbc.J2EE13Compliant=true

1

si vous utilisez Oracle 10g, et vos colonnes de nombre défini avec le numéro et pas de taille à l'échelle

create table EXAMPLE 
(
FILED1 NUMBER(2,0), 
FILED2 NUMBER 
)  

tout en peuplant FIELD2, vous recevrez cette exception .

Vérifiez la structure de votre table pour les champs numériques.

J'espère que cela peut vous aider.

Questions connexes