Ich habe eine Abfrage, dieOracle10 und JDBC: wie CHAR nachfolgende Leerzeichen beim Vergleich ignorieren?
hat ... WHERE PRT_STATUS = 'ONT' ...
Das prt_status Feld als CHAR (5), obwohl definiert ist. Es wird also immer mit Leerzeichen aufgefüllt. Die Abfrage stimmt mit nichts überein. Um diese Abfrage Arbeit zu machen habe ich
... WHERE rtrim (PRT_STATUS) = 'ONT'
die Arbeit erledigt zu tun.
Das ist ärgerlich.
Zur gleichen Zeit, ein paar pure-Java-DBMS-Clients (Oracle SQLDeveloper und AquaStudio) Ich habe kein Problem mit der ersten Abfrage, sie geben das richtige Ergebnis zurück. TOAD hat auch kein Problem.
Ich nehme an, dass sie die Verbindung einfach in einen Kompatibilitätsmodus (z. B. ANSI) versetzen, so dass das Oracle weiß, dass CHAR (5) ohne Rücksicht auf nachfolgende Zeichen erwartet wird.
Wie kann ich es mit Connection-Objekten, die ich in meiner Anwendung bekomme?
UPDATE Ich kann das Datenbankschema nicht ändern.
LÖSUNG Es war in der Tat die Art, wie Oracle Felder mit übergebenen Parametern vergleicht.
Wenn die Bindung abgeschlossen ist, wird die Zeichenfolge über PreparedStatement.setString() übergeben, wodurch der Typ auf VARCHAR festgelegt wird. Daher verwendet Oracle ungepolten Vergleich - und schlägt fehl.
Ich habe versucht, SetObject (n, str, Types.CHAR) zu verwenden. Schlägt fehl. Dekompilierung zeigt, dass Oracle CHAR ignoriert und es als VARCHAR erneut übergibt.
Die Variante, die schließlich funktioniert, ist
setObject(n,str,OracleTypes.FIXED_CHAR);
Es macht den Code aber nicht tragbar.
Die UI-Clients sind aus einem anderen Grund erfolgreich - sie verwenden Zeichenliterale, die nicht bindend sind. Wenn ich PRT_STATUS = 'ONT' eintippe, ist 'ONT' ein Literal und wird daher mit einem gepolsterten Weg verglichen.
Das ist in Ordnung. Siehe meine aktualisierte Antwort dann. – vladr
Hmm ... das macht Sinn. JDBCs setString verwendet VARCHAR, um einen Zeichenfolgenparameter zu binden. Ich bin mir nicht sicher, ob ich damit das Problem lösen kann, aber zumindest wird es jetzt klarer. –
Sie haben wahrscheinlich Recht: "Oracle verwendet nicht gepackte Vergleichssemantik, wenn einer oder beide Werte im Vergleich den Datentyp VARCHAR2 oder NVARCHAR2 haben". Ich muss einen Test machen, um es zu überprüfen. –