Oracle-JDBC und Oracle-Datentyp CHAR
Ich habe ein tricky Problem mit Oracle-JDBC-Treibers-handling von CHAR
Datentypen. Nehmen wir diese einfache Tabelle:
create table x (c char(4));
insert into x (c) values ('a'); -- inserts 'a '
So, wenn ich etwas einfügen in CHAR(4)
, der string ist immer gefüllt mit Leerzeichen. Dies wird auch gemacht, wenn ich die Abfragen ausführen, wie diese:
select * from x where c = 'a'; -- selects 1 record
select * from x where c = 'a '; -- selects 1 record
select * from x where c = 'a '; -- selects 1 record
Hier, die ständige 'a'
ist gefüllt mit Leerzeichen, so gut. Das ist, warum der Datensatz wird immer zurückgegeben. Dies gilt jedenfalls dann, wenn diese Abfragen ausgeführt werden, mithilfe einer JDBC - PreparedStatement
als gut. Jetzt die heikle Sache ist, wenn ich verwenden möchten, eine bind-variable:
PreparedStatement stmt =
conn.prepareStatement("select * from x where c = ?");
stmt.setString(1, "a"); //This won't return any records
stmt.setString(1, "a "); //This will return a record
stmt.executeQuery();
Dies ist eine Problemumgehung:
PreparedStatement stmt =
conn.prepareStatement("select * from x where trim(c) = trim(?)");
stmt.setString(1, "a"); //This will return a record
stmt.setString(1, "a "); //This will return a record
stmt.executeQuery();
BEARBEITEN: dies sind die Einschränkungen:
- Die oben beschriebenen Problemumgehung nicht wünschenswert, da es ändert sowohl den Inhalt
c
und?
, UND es macht Verwendung von Indizes aufc
ziemlich hart. - Verschieben Sie die Spalte aus
CHAR
zuVARCHAR
(was es sein sollte, natürlich) ist nicht möglich
BEARBEITEN: Die Gründe für diese Einschränkungen ist, weil ich diese Frage aus der Sicht der Entwickler von jOOQ, einen database abstraction library. Also meine Anforderungen sind, um eine sehr generische Lösung, die nicht etwas zu brechen, in jOOQ ist der client-code. Das ist, warum ich bin nicht wirklich ein großer fan von dem workaround. Und das ist, warum ich don ' T haben Zugang zu diesem CHAR
Spalte in der Erklärung. Aber trotzdem, ich möchte in der Lage sein, in diesem Fall behandeln.
Was würden Sie stattdessen tun? Was ist eine gute übung für den Umgang CHAR
Daten-Typen, wenn ich will, Sie zu ignorieren Leerzeichen?
- Auch wenn Sie feststellen, dass eine änderung von VARCHAR ist keine option (warum?), VARCHAR ist die einzig sinnvolle Lösung für Ihre Anforderung.
- Ich Stimme mit Ihnen überein. Ich werde erklären, in meiner Frage
Du musst angemeldet sein, um einen Kommentar abzugeben.
Wenn Sie möchten,
Rückgabe eines Datensatzes, versuchen
CHAR(4)
. Auf der anderen Seite, würde ich brauchen, um zu wissen, die genaue Länge der Spalte (das problem ist, dassX
undC
in meinem Beispiel sind beliebige Platzhalter...Sehe ich keinen Grund für die Verwendung von CHAR-Datentyp, auch wenn es char(1) in Oracle. Können Sie ändern den Datentyp statt?
CHAR
können nützlich sein für die codes, ISO country/language/currency codes, etc. Aber ich Stimme mit Ihnen, als auch dann, es spielt keine große Rolle. Könnten SieVARCHAR
als gut.Gary ' s Lösung funktioniert gut. Hier ist eine alternative.
Wenn Sie eine Oracle-JDBC-Treiber, der Aufruf
prepareStatement()
tatsächlich eine RückkehrOraclePreparedStatement
, die einesetFixedCHAR()
Methode, die pads automatisch Ihre Eingaben mit Leerzeichen.Natürlich, der cast ist nur sicher, wenn Sie den Oracle-Treiber.
Der einzige Grund, warum ich würde vorschlagen, dass Sie dies nicht über Gary ' s Antwort ist, dass Sie ändern können, Ihre Spalte Größen zimmerreserviereung, ohne das Sie ändern Sie Ihre JDBC-code. Der Fahrer pads die richtige Anzahl von Leerzeichen, ohne dass der Entwickler brauchen, um wissen/managen der Spalte Größe.
Habe ich sehr schöne Lösung für dieses Problem. Haben Sie zum hinzufügen einer Eigenschaft, während die erste Verbindung aus der Datenbank.
oder in Java-Verbindung können Sie folgenden code verwenden:
der andere Weg ist, ändern Sie Ihre sql als