Oracle 10 et JDBC: comment faire en sorte que CHAR ignore les espaces à la fin de la comparaison?

StackOverflow https://stackoverflow.com/questions/603245

  •  03-07-2019
  •  | 
  •  

Question

J'ai une requête qui a

  

... WHERE PRT_STATUS = 'ONT' ...

Le champ prt_status est défini par CHAR (5) cependant. Donc, il est toujours rempli d'espaces. La requête ne correspond à rien comme résultat. Pour que cette requête fonctionne, je dois le faire

  

... WHERE rtrim (PRT_STATUS) = 'ONT'

qui fonctionne.

C'est embêtant.

En même temps, quelques clients SGBD pure-java (Oracle SQLDeveloper et AquaStudio) ne rencontrent PAS de problème avec la première requête, ils renvoient le résultat correct. TOAD n'a pas de problème non plus.

Je suppose qu'ils mettent simplement la connexion en mode de compatibilité (par exemple ANSI), de sorte que Oracle sait que CHAR (5) doit être comparé sans aucun respect des caractères de fin.

Comment puis-je le faire avec les objets de connexion contenus dans mon application?

UPDATE Je ne peux pas modifier le schéma de base de données.

SOLUTION C’est ainsi que Oracle compare les champs avec les paramètres passés.

Lorsque la liaison est terminée, la chaîne est transmise via PreparedStatement.setString (), qui définit le type sur VARCHAR. Oracle utilise donc la comparaison non rajoutée et échoue.

J'ai essayé d'utiliser setObject (n, str, Types.CHAR). Échoue. La décompilation montre qu'Oracle ignore CHAR et le transmet à nouveau en tant que VARCHAR.

La variante qui fonctionne enfin est

setObject(n,str,OracleTypes.FIXED_CHAR);

Cela rend le code non portable cependant.

Les clients de l'interface utilisateur réussissent pour une raison différente: ils utilisent des littéraux de caractères, sans obligation. Lorsque je tape PRT_STATUS = 'ONT', 'ONT' est un littéral et, en tant que tel, comparé à l'aide d'une méthode de remplissage.

Était-ce utile?

La solution

Notez que compare Oracle CHAR en utilisant une sémantique de comparaison complétée par des blancs.

De Règles de comparaison des types de données ,

  

Oracle utilise une comparaison complétée par des blancs   la sémantique que lorsque les deux valeurs dans le   la comparaison sont soit des expressions de   type de données CHAR, NCHAR, littéraux de texte,   ou valeurs renvoyées par l'utilisateur   fonction.

Dans votre exemple, 'ONT' est-il passé en tant que paramètre de liaison ou est-il intégré à la requête sous forme de texte, comme vous l'avez illustré? S'il s'agit d'un paramètre de liaison, assurez-vous qu'il est lié au type CHAR . Sinon, vérifiez la version de la bibliothèque client utilisée, car les versions réellement anciennes d'Oracle (par exemple v6) auront une sémantique de comparaison différente pour CHAR .

Autres conseils

Si vous ne pouvez pas modifier votre table de base de données, vous pouvez modifier votre requête.

Quelques alternatives pour RTRIM:

  

.. WHERE PRT_STATUS aime "ONT%" ...

     

.. WHERE PRT_STATUS = 'ONT' ... - 2 espaces blancs derrière T

     

.. WHERE PRT_STATUS = rpad ('ONT', 5, '') ...

Je changerais la colonne CHAR (5) en varchar2 (5) en db.

Vous pouvez utiliser l'opération cast to char dans votre requête:

... WHERE PRT_STATUS=cast('ONT' as char(5))

Ou de manière plus générique JDBC:

... WHERE PRT_STATUS=cast(? as char(5))

Dans votre code JDBC, utilisez statement.setString (1, "ONT");

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