Oracle 10 und JDBC: wie man CHAR nachgestellte Leerzeichen am Vergleich ignorieren?
Frage
Ich habe eine Abfrage, die hat
obwohl... WHERE PRT_STATUS = 'ONT' ...
Das prt_status Feld wird als CHAR (5) definiert. So ist es immer mit Leerzeichen aufgefüllt. Die Abfrage entspricht nichts als das Ergebnis. Um diese Abfrage Arbeit machen muss ich tun
... WHERE rtrim (PRT_STATUS) = 'ONT'
, die funktioniert.
Das ist ärgerlich.
Zur gleichen Zeit, ein paar pure-Java-DBMS-Clients (Oracle sqldeveloper und AquaStudio) Ich habe haben kein Problem mit der ersten Abfrage, kehren sie das richtige Ergebnis. TOAD hat kein Problem.
Ich nehme sie einfach die Verbindung in eine Kompatibilitätsmodus setzen (zum Beispiel ANSI), so dass der Oracle weiß, dass CHAR (5) erwartet ohne Respekt verglichen werden Zeichen Hinter.
Wie kann ich es mit Verbindungsobjekten kann ich in meiner Anwendung erhalten?
UPDATE Ich kann das Datenbankschema ändern.
SOLUTION Es war in der Tat die Art und Weise Oracle in Parametern Felder mit geben vergleicht.
Wenn binden getan wird, wird die Zeichenfolge über PreparedStatement.setString () übergeben, die Typ VARCHAR setzt und damit Oracle verwendet unpadded Vergleich -. Und nicht
Ich habe versucht, setObject zu verwenden (n, str, Types.CHAR). Ausfällt. Decompilation zeigt, dass Oracle ignoriert CHAR und übergibt sie in als VARCHAR wieder.
Die Variante, die schließlich funktioniert, ist
setObject(n,str,OracleTypes.FIXED_CHAR);
Es macht den Code aber nicht tragbar.
Die UI-Clients erfolgreich aus einem anderen Grund - sie Zeichenliterale verwenden, nicht bindend. Als ich PRT_STATUS = ‚ONT‘ Typ ‚ONT‘ ist eine wörtliche, und als solche im Vergleich gepolsterte Art und Weise verwendet wird.
Lösung
Beachten Sie, dass Oracle CHAR
Werte vergleicht mit Leerzeichen aufgefüllt Vergleich Semantik.
Oracle verwendet Leerzeichen aufgefüllt Vergleich Semantik nur dann, wenn beide Werte in der Vergleich sind entweder Ausdrücke Datentyp CHAR, NCHAR, Textliterale, oder Werte, die durch den Benutzer zurückgegeben Funktion.
In Ihrem Beispiel wird 'ONT'
als Bind-Parameter übergeben, oder wird es in die Abfrage textlich gebaut, wie Sie dargestellt? Wenn ein Bind-Parameter, dann stellen Sie sicher, dass es als Typ CHAR
gebunden ist. Andernfalls überprüfen Sie die Client-Bibliothek Version verwendet wird, als wirklich alte Versionen von Oracle (z v6) unterschiedliche Vergleichssemantik für CHAR
haben.
Andere Tipps
Wenn Sie nicht Ihre Datenbanktabelle ändern können, können Sie Ihre Abfrage ändern.
Einige Alternativen für RTRIM:
.. WHERE PRT_STATUS wie 'ONT%' ...
.. WHERE PRT_STATUS = 'ONT' ... - 2 weißen Räume hinter T
.. WHERE PRT_STATUS = rpad ( 'ONT', 5‘‚) ...
Ich würde CHAR (5) Spalte in varchar2 (5) in db ändern.
Sie können cast char Operation in Ihrer Abfrage verwenden:
... WHERE PRT_STATUS=cast('ONT' as char(5))
oder in allgemeinerer JDBC Art und Weise:
... WHERE PRT_STATUS=cast(? as char(5))
Und dann in Ihrem JDBC-Code verwenden statement.setString(1, "ONT");