Question

J'utilise le pilote léger JDBC d'Oracle (10.2.0.3) pour me connecter à une base de données Oracle 10g. J'aimerais obtenir des informations sur les colonnes de la base de données. J'utilise donc ResultSetMetaData . Les informations les plus importantes dont j'ai besoin sont le type de la colonne et sa longueur, aussi j'utilise getColumnType , getPrecision , et méthodes getScale .

Cela fonctionne pour une requête simple (, sélectionnez * dans le nom du fichier ) si le type de colonne est " simple " comme VARCHAR2 (50), NUMBER (5), NUMBER (6,2) . Si j'ai une requête plus complexe ( select count (*) from tablename ) ou une requête basée sur une vue contenant des calculs complexes, les méthodes donnent des résultats étranges tels que:

  • getScale : -127
  • getPrecision et getScale ont la valeur 0
  • getPrecision : -1

La définition de la propriété de connexion oracle.jdbc.J2EE13Compliant sur true (comme suggéré par plusieurs pages Web) élimine getScale = -127 mais renvoie toujours le résultat 0/0.

Il est fort probable que je doive créer une solution de contournement pour ces résultats étranges, mais tout d’abord, il me faut au moins une documentation complète sur le comportement de ResultSetMetaData d’Oracle. Par exemple, une table volumineuse avec la signification de getPrecision / getScale pour tous les types SQL serait formidable. Y a-t-il une documentation comme celle-ci quelque part?

Était-ce utile?

La solution

Oracle ne peut pas retourner un type basé sur une vue ou sur le nombre count (*) car il n'a pas été déclaré explicitement. Votre vue peut renvoyer n'importe quelle précision ou échelle en fonction des tables sous-jacentes de la vue.

Pour résoudre ce problème, vous devez convertir le type dans votre requête ou la vue comme ceci:

select CAST (count(*) AS NUMBER(30))

Autres conseils

Une alternative consiste à interroger user_tab_columns ou all_tab_columns .

Une échelle de 0 est acceptable: un NUMBER (5) est identique à un NUMBER (5,0)

La précision doit cependant être un entier compris entre 1 et 38 lorsqu’elle est définie. Lorsqu'il n'est pas défini, comme dans NUMBER, le pilote doit renvoyer quelque chose, car il ne peut pas renvoyer null. Dans ce cas, le pilote choisit de renvoyer 0.

Il me semble qu’il n’existe pas de documentation complète sur ResultSetMetaData. Guide du développeur JDBC pour Oracle® Base de données et référence 10g version 2 ( 10.2) et 11g version 2 (11.2). ) donne un exemple concernant le nom de colonne et tapez ici , ils ne traitent pas d'autres aspects.

Quelqu'un a un problème similaire avec PostgreSQL il y a des années et il a fait un patch. Peut-être que Oracle utilise la même base de code ici.

Vous pouvez essayer d'utiliser le fichier ojdbc14 _g .jar au lieu du fichier ojdbc14.jar, car ses classes ont été compilées avec "javac -g". et contiennent des informations de traçage.

Vous pouvez également essayer nouveaux pilotes .

Vous pouvez utiliser le rs.getBigDecimal (columnIndex) et, à partir de la grande décimale, vous pouvez obtenir les valeurs de précision / d'échelle des colonnes spécifiques.

Ce n'est pas une réponse directe à votre question, mais une solution de contournement que vous avez mentionnée:

Si tout ce que vous avez à faire est de vérifier ou de comparer les schémas de base de données, alors, au lieu de ResultSetMetaData et de l'interrogation de toutes les tables, utilisez les informations de schéma Oracle comme décrit dans Reverse engineering d'un modèle de données . Je l'ai utilisé dans mon utilitaire pour exporter ces informations vers du texte

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top