2017-09-13 2 views
2

J'ai récemment rencontré un problème en essayant de récupérer un CLOB valeur de Oracle DB avec Java. Il existe une table qui stocke les fichiers XML en tant que CLOB. NLS_CHARACTERSET est défini sur AL32UTF8. Si j'essaie de récupérer une valeur avec le package java.sql et en utilisant ResultSet.getClob().getAsciiStream() qui convertit ensuite en chaîne avec le codage UTF-8, j'obtiens un code XML valide. Mais si j'utilise ResultSet.getString(), l'analyseur XML échoue avec une exception d'analyse.java.sql.ResultSet.getString() retourne la chaîne avec des caractères supplémentaires

Lors du débogage, la valeur extraite ressemble à this. Et il contient seulement la moitié du fichier. Les autres fichiers XML peuvent être sélectionnés avec ResultSet.getString() sans problème.
Je n'ai vu aucune différence notable dans la représentation ASCII de XML corrompu et valide.
Le problème est résolu lorsque vous réinsérez la même valeur dans la base de données.

Pouvez-vous expliquer ce comportement de ResultSet.getString()?

Informations sur Oracle

Oracle version is 12.1.0.2.0. 

Informations sur JDK:

java version "1.7.0_131" 
OpenJDK Runtime Environment (rhel-2.6.9.0.0.1.el7_3-x86_64 u131-b00) 
OpenJDK 64-Bit Server VM (build 24.131-b00, mixed mode) 

Répondre

-1

Je crois que son adresse de CLOB retour stockées pour une raison quelconque et quand vous obtenez avec getCLOB cela rend XML .

Vérifiez votre XML stocké, vous risquez d'oublier la fermeture d'un tag ou d'avoir d'autres problèmes de syntaxe dans votre fichier XML stocké.

+0

Les deux 'ResultSet.getString()' et 'ResultSet.getClob()' renvoyer des données du fichier stocké, j'ai vérifié. Le XML stocké est valide. Et comme je l'ai souligné, l'erreur disparaît si j'insère la même valeur dans la base de données –

1

Pour moi, il semble que ce clob particulier n'est pas réellement codé en UTF-8 comme il le prétend, mais en UTF-16. Il peut parfois arriver que data can be written to a column using a charset other than the NLS_CHARACTERSET. Cela explique pourquoi le problème est résolu lorsque les données sont réinsérées en utilisant le jeu de caractères local correct.

Je suppose que le Clob.getAsciiStream() a une logique supplémentaire pour traiter ce genre de chose - peut-être pour overlong (00-padded) UTF-8 incorrectement codé, qui est indiscernable de UTF-16 pour les points de code ASCII.