7 Stimmen

Das Einfügen nationaler Zeichen in eine NCHAR- oder NVARCHAR-Spalte von Oracle funktioniert nicht

Beim Einfügen von Zeichenketten in eine Oracle-Datenbank werden einige nationale Zeichen durch Fragezeichen ersetzt, auch wenn sie in eine NCHAR- oder NVARCHAR-Spalte eingefügt werden, die in der Lage sein sollte, alle Unicode-Zeichen zu verarbeiten.

Dies geschieht entweder mit dem SQL Developer von Oracle, mit sqlplus oder mit dem JDBC-Treiber.

Die Datenbank NLS_CHARACTERSET ist auf WE8ISO8859P1 (westeuropäisch iso-8859-1) eingestellt. Der für NCHAR-Spalten verwendete NLS_NCHAR_CHARACTERSET ist auf AL16UTF16 (UTF-16) eingestellt.

Jedes Zeichen, das nicht im NLS_CHARACTERSET enthalten ist, wird offenbar durch ein umgekehrtes Fragezeichen ersetzt.

27voto

KarlP Punkte 5059

Bearbeiten: Beachten Sie, dass der beste Weg, um UTF auf Oracle zu behandeln, ist, die Datenbank mit dem Datenbankzeichensatz AL32UTF8 zu erstellen und normale varchar2-Spalten zu verwenden. Eines der Probleme bei der Verwendung von nchar-Spalten ist, dass Oracle keine Indizes für normale char/varchar2-Spalten verwenden kann, wenn Argumente standardmäßig als nchar gesendet werden.

Wie auch immer: Wenn Sie die Datenbank nicht konvertieren können:


Erstens muss Unicode-Literalen ein 'n' vorangestellt werden, etwa so:

select n'Language - Språk - Jezyk' from dual;

*) 8-Bit-Kodierungen können diesen Text nicht verarbeiten

Leider ist das nicht genug.

Aus irgendeinem Grund ist das Standardverhalten für Datenbankclients, alle Stringliterale in den Datenbankzeichensatz zu übersetzen, Das bedeutet, dass die Werte geändert werden, noch bevor die Datenbank die Zeichenkette zu sehen bekommt.

Die Clients benötigen einige Konfigurationen, um ein Unicode-Zeichen in eine NCHAR- oder NVARCHAR-Spalte einfügen zu können:

SQL Plus unter Unix

Diese Umgebungsvariablen richten die Unix-Umgebung und Sqlplus für die Verwendung von UTF-8-Dateien ein, und konfigurieren sqlplus so, dass es String-Literale in Unicode sendet.

NLS_LANG=AMERICAN_AMERICA.AL32UTF8
LC_CTYPE="en_US.UTF-8"
ORA_NCHAR_LITERAL_REPLACE=true

(en_US.UTF-8 ist für Solaris - Linux oder andere Systeme benötigen möglicherweise andere Zeichenketten, verwenden Sie locale -a um die unterstützten Sprachumgebungen aufzulisten).

JDBC-Treiber

Anwendungen, die Oracles JDBC-Treiber verwenden, müssen die folgende Systemeigenschaft definieren, um Zeichenkettenliterale in Unicode zu senden.

-Doracle.jdbc.defaultNChar=true 
-Doracle.jdbc.convertNcharLiterals=true

SQL-Entwickler

Suchen Sie die Datei sqldeveloper.conf und fügen Sie die folgenden Zeilen hinzu:

AddVMOption -Doracle.jdbc.defaultNChar=true 
AddVMOption -Doracle.jdbc.convertNcharLiterals=true

SQL Plus unter Microsoft Windows

Ich habe nicht ausprobiert, ob SQLplus unter Microsoft Windows oder Toad überhaupt mit utf-8 umgehen kann. Sqlplusw.exe kann das tun, und die folgenden Registrierungseinstellungen können den Trick bewirken.

NLS_LANG=AMERICAN_AMERICA.AL32UTF8
ORA_NCHAR_LITERAL_REPLACE=true

1voto

Simon Clewer Punkte 391

Danke KarlP - das hat mich in Schwung gebracht. Ich fasse zusammen, was für mich funktioniert hat.

Einfügen von chinesischem (beliebigem utf8) Text in eine nvarchar-Spalte einer Nicht-Unicode-Datenbank (z. B. ISO8859 usw.) unter Verwendung von sqlplus auf Linux.

Diese db params auf meinem System, beachten Sie eine Single-Byte-Kodierung für char, aber Multibyte für nchare. NLS_CHARACTERSET WE8ISO8859P1
NLS_NCHAR_CHARACTERSET AL16UTF16

z. B:

INSERT INTO tt values ( N'' );

Das 'N' vor der Zeichenfolge ist wichtig. Außerdem muss die Umgebungsvariable vor dem Start von sqlplus gesetzt werden,

# Important to tell sqldeveloper what encoding is needed.
export NLS_LANG=AMERICAN_AMERICA.UTF8
# Others might find AMERICAN_AMERICA.AL32UTF8 or whatever better suits.

# ** THIS MATTERS - DOES NOT WORK WITHOUT !! 
export ORA_NCHAR_LITERAL_REPLACE=true

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X