Oracle 12c/19c - NON-ASCII Zeichen in CLOBS funktionieren mit JDBC-thin nicht
Oracle hat immer wieder Probleme mit Special Characters – also alle Zeichen, die nicht Teil von US7ASCII sind. Grundsätzlich gibt es seit Oracle 7 das Konzept von Zeichensätzen und der Zeichenkonvertierung (in Oracle 6 gab es keine Zeichenkonvertierung) zwischen verschiedenen Zeichensätzen, allerdings patzt Oracle dabei immer wieder. Die Zeichenkonvertierung kann bei Oracle wahlweise am Client (bevorzugt) oder am Datenbank Server selbst erfolgen, wobei es am Datenbank Server eigentlich immer funktioniert, weil hier immer alle unterstützten Zeichensätze vorhanden sein müssen. Die Konvertierung am Client kann nur dann erfolgen, wenn der Client sowohl seinen eigenen als auch den Zeichensatz des Servers kennt und unterstützt. Im Fall von CLOBs wird ein Unicode Zeichensatz – meist AL32UTF8 – genutzt, der aber nicht auf jedem Client verfügbar ist. Das ist bei JDBC der Fall. Zwar kennt JDBC ebenfalls UNICODE, allerdings nur einen Teil davon. Das bedeutet, dass die Konvertierung nur auf dem Datenbank Server korrekt erfolgen kann...
Leider hat Oracle es geschafft, dass der Bug 26380097 in Oracle 12.2 fälschlicherweise die Konvertierung am Client erwartet, wodurch alle Special Characters – somit beispielsweise alle unsere Umlaute – zu Datenmüll werden.
Für diesen Fehler, der mit Oracle 18c behoben ist, gibt es einen One-Off Patch bzw. ist dieser in vielen RUs - ab Mitte 2018 – enthalten. Siehe auch Note 26370097.8.
Wenn man jetzt auf Oracle 19c (aktuell inkl. 19.7) umsteigt, ist genau dieser Fehler wieder da! Oracle hat dafür einen neuen Bug 31244237 geöffnet. So wie es aussieht, handelt es sich um den gleichen Fehler, der erst im Oracle 21c Basiscode behoben ist. Aktuell – Stand von Ende Juni 2020 – sind Backports auf Oracle 19c und 20c geplant, die sind aber noch nicht verfügbar. Sofern Oracle die Fehlernummer nicht durch einen anderen ersetzt, sollten die One-off Patches hier zu finden sein, sobald diese fertiggestellt sind.
Das Problem tritt nicht immer und in jeder Konstellation auf, es ist aber reproduzierbar, wenn am Client ein WE8/EE8 Zeichensatz zum Einsatz kommt.
Alternative Workarounds
Das Problem ist JDBC-Thin – also die schlanke Version des JDBC Treibers, der aus Platzgründen keine zusätzlichen Zeichensätze enthält. Wenn jedoch JDBC-OCI eingesetzt wird, sollte das Problem nicht auftreten.
Wenn am Client als Zeichensatz AL32UTF8 zum Einsatz kommt, erfolgt keinerlei Konvertierung und das Problem tritt ebenfalls nicht auf.