2011-06-28 17 views
6

Al insertar cadenas en una base de datos Oracle, algunos caracteres nacionales se reemplazan con signos de interrogación, aunque están insertados en una columna NCHAR o NVARCHAR, que deberían poder para manejar todos los caracteres Unicode.Insertar caracteres nacionales en una columna oráculo NCHAR o NVARCHAR no funciona

Esto sucede utilizando Oracle SQL Developer, sqlplus o usando el controlador JDBC.

La base de datos NLS_CHARACTERSET se establece en WE8ISO8859P1 (western western iso-8859-1) El NLS_NCHAR_CHARACTERSET utilizado para columnas NCHAR se establece en AL16UTF16. (UTF-16)

Cualquier carácter que no se encuentre en el NLS_CHARACTERSET parece ser reemplazado por un signo de interrogación invertido.

+0

Estoy auto responder a esta ya he pasado una semana calcular esto ... espero que Google lo encuentra ... – KarlP

+0

Tenga en cuenta que el buen camino para admitir UTF8 en Oracle, es crear la base de datos usando el juego de caracteres de la base de datos AL32UTF8, y usar columnas ordinarias varchar2. – KarlP

Respuesta

19

Editar: Tenga en cuenta que la mejor manera de manejar UTF en Oracle es crear la base de datos utilizando el conjunto de caracteres de la base de datos AL32UTF8, y utilizar columnas ordinarias varchar2. Uno de los problemas con el uso de columnas nchar es que Oracle no puede usar índices para las columnas ordinarias char/varchar2 cuando los argumentos se envían como nchar de manera predeterminada.

De todos modos: Si no se puede convertir la base de datos:


En primer lugar, los literales Unicode tiene que ser precedido de una 'N', así:

select n'Language - Språk - Język' from dual; 

*) Las codificaciones de 8 bits no pueden manejar este texto

Lamentablemente, eso no es suficiente. Por alguna razón, el comportamiento predeterminado para los clientes de bases de datos es traducir todos los literales de cadena al conjunto de caracteres de la base de datos, , lo que significa que los valores se cambiarán incluso antes de que la base de datos vea la cadena.

Los clientes necesitan alguna configuración con el fin de ser capaz de insertar un carácter Unicode en un NCHAR o NVARCHAR columna:

SQL Plus en Unix

Estas variables environemnet configura el entorno UNIX y sqlplus para usar archivos UTF-8, y también configure sqlplus para enviar literales de cadenas en Unicode.

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

(en_US.UTF-8 es para Solaris -. Linux u otros sistemas pueden necesitar diferentes cadenas, utilice locale -a a la lista localizaciones soportadas)

controlador JDBC

Las aplicaciones que utilizan los oráculos JDBC el controlador necesita tener la siguiente propiedad del sistema definida para enviar cadenas literales en Unicode.

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

SQL Developer

Localizar sqldeveloper.conf, y añadir las siguientes líneas:

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

SQL Plus en Microsoft Windows

no he probado si SQLPLUS en Microsoft Windows o sapo maneja UTF-8 en absoluto. Sqlplusw.exe puede hacer eso, y la siguiente configuración de registro puede hacer el truco.

NLS_LANG=AMERICAN_AMERICA.AL32UTF8 
ORA_NCHAR_LITERAL_REPLACE=true 
+0

¿Puedes explicarnos cómo hacerlo para Microsoft SQL Express 2005? – CyprUS

+0

En general. Con respecto a Java, los controladores jdbc y visual studio funcionan de manera automática, si el tipo de columna es nchar y los literales tienen el prefijo n. – KarlP

+0

¿Sabes cómo configurar esto para los controladores .NET System.Data.OracleClient? –

0

Gracias KarlP - that got me going. Recapitulando lo que funcionó para mí.

Insertar texto chino (cualquier utf8) en una columna nvarchar de una base de datos no unicode (p. Ej .: ISO8859, etc.), usando sqlplus en linux.

Estos parámetros db en mi sistema, tenga en cuenta una codificación de un solo byte para char, pero multibyte para nchare. NLS_CHARACTERSET WE8ISO8859P1
NLS_NCHAR_CHARACTERSET AL16UTF16

por ejemplo:

INSERT INTO tt values (N'气前照灯'); 

El 'N' anteponiendo la cadena es importante. Además, debe establecer el env antes de comenzar sqlplus,

# 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 
+0

Así no se supone que es una respuesta. Se supone que una respuesta le muestra al OP una solución solo para su problema, pero ya existe una solución adecuada. Tu respuesta es redundante y no pertenece aquí. Sé que eres nuevo en Stack Overflow, pero esa no es la forma en que se acepta comúnmente una respuesta aquí. Lo siento, pero espero que me entiendas, por favor considera eliminar tu respuesta. :-) –

Cuestiones relacionadas