Oracle 10 und JDBC: wie man CHAR nachgestellte Leerzeichen am Vergleich ignorieren?

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

  •  03-07-2019
  •  | 
  •  

Frage

Ich habe eine Abfrage, die hat

  

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

obwohl

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.

War es hilfreich?

Lösung

Beachten Sie, dass Oracle CHAR Werte vergleicht mit Leerzeichen aufgefüllt Vergleich Semantik.

Datentyp Vergleichsregeln ,

  

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");

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top