Datos de caracteres se representan incorrectamente cuando la página de códigos del equipo cliente difiere de la página de códigos de la base de datos en SQL Server 2005


Síntomas


Imagine el siguiente escenario:
  • En Microsoft SQL Server 2005, utilice SQL Server Management Studio para consultar los datos de caracteres desde una base de datos de SQL Server que utiliza un tipo de datos no Unicode. Por ejemplo, la base de datos de SQL Server utiliza el tipo de datos char , el tipo de datos varchar o el tipo de datos texto .
  • La página de códigos del equipo cliente difiere de la página de códigos de la base de datos. La página de códigos se asocia a la intercalación de la base de datos.
En este escenario, datos de caracteres se representan incorrectamente.


Por ejemplo, puede experimentar uno de los siguientes problemas:
  • Los datos de carácter se representan como un signo de interrogación (?). Este problema puede aparecer si se inserta o actualización los datos de caracteres como un tipo de datos no Unicode antes de consultar los datos de caracteres. Este problema se produce si realiza este cambio utilizando SQL Server Management Studio en un equipo cliente que tiene una página de código diferente.
  • Los datos de carácter se representan como datos dañados. Los datos de caracteres de página de códigos X se almacenan en una columna no Unicode de la página de códigos Y. Además, los datos de caracteres no se traducen. Este problema se produce al consultar los datos de caracteres utilizando SQL Server Management Studio.

    Nota: Al consultar los datos de caracteres utilizando el analizador de consultas de SQL en Microsoft SQL Server 2000, los datos de caracteres se representan correctamente si el
    Realizar conversión de los datos de carácter (el parámetro de Traducción automática ) está deshabilitada. El parámetro de Traducción automática es un parámetro de la propiedad ConnectionString para el proveedor Microsoft OLE DB para SQL Server y para el proveedor de datos de Microsoft.NET Framework para OLE DB.

Causa


Este problema se produce porque los datos de caracteres de página de códigos
X se almacena en una columna no Unicode de página de códigos
Y. Además, los datos de caracteres no se convierten correctamente. No se admite el almacenamiento de los datos de caracteres de página de códigos
X en una columna de la página de códigos
Y.

En SQL Server 2005, cuando se utiliza un literal de cadena de un tipo de datos no Unicode, se convierte el literal de cadena utilizando la página de códigos predeterminada de la base de datos que se deriva de la intercalación de la base de datos. Almacenar los datos de caracteres de página de códigos X en una columna de la página de códigos Y puede provocar pérdida de datos o daños en los datos.

Si los datos de carácter se representan como datos dañados, los datos se pueden representar correctamente sólo si deshabilita el parámetro de Traducción automática para el proveedor de Microsoft OLE DB para SQL Server o el proveedor de datos de Microsoft.NET Framework para OLE DB.

Nota: SQL Server Management Studio utiliza el proveedor de datos de Microsoft.NET Framework para SQL Server para conectarse a la base de datos de SQL Server. Este proveedor de datos no admite el parámetro de Traducción automática .

Solución alternativa


Para evitar este problema, utilice uno de los métodos siguientes.

Método 1: Usar un tipo de datos Unicode en lugar de un tipo de datos no Unicode

Cambiar las columnas a un tipo de datos Unicode para evitar todos los problemas causados por la traducción de página de código. Por ejemplo, utilice el tipo de datos nchar , el tipo de datos nvarchar o el tipo de datos ntext .

Para obtener más información sobre cómo almacenar datos Unicode, haga clic en el número de artículo siguiente para verlo en Microsoft Knowledge Base:
239530 debe preceder a todas las cadenas de Unicode con un prefijo N al tratar con las constantes de cadena Unicode en SQL Server

Método 2: Utilizar una intercalación apropiada para la base de datos

Si debe utilizar un tipo de datos no Unicode, asegúrese siempre de que la página de códigos de la base de datos y la página de códigos de las columnas no Unicode pueden almacenar los datos no Unicode correctamente. Por ejemplo, si desea almacenar datos de caracteres de código página 949 (coreano), utilice una intercalación coreana para la base de datos. Por ejemplo, utilice la intercalación Korean_Wansung_CI_AS de la base de datos.

Método 3: Usar el tipo de datos binarios o el tipo de datos varbinary

Si desea que la base de datos directamente, almacenar y recuperar los valores de bytes exacto de los caracteres que se manejan sin intentar realizar la traducción de página de código apropiado, utilice el tipo de datos binario o el tipo de datos varbinary .

Método 4: Utilizar una herramienta diferente para almacenar y recuperar datos y deshabilitar el parámetro de traducción automática

Advertencia: No prueba ni admite almacenar los datos de caracteres de página de códigos
X en una columna de la página de códigos
Y. esta operación puede producir resultados lingüísticamente incorrectos, coincidencia de cadena incorrecto o pedidos y traducción de página de código inesperada (daños en los datos). Le recomendamos que utilice uno de los otros métodos para solucionar temporalmente este problema.

Al utilizar el proveedor Microsoft OLE DB para SQL Server para conectarse a una base de datos que tiene una página de código diferente e intenta consultar los datos de carácter de una columna de tipo de datos no Unicode, debe asegurarse de almacenar los caracteres sin traducir la base de datos.

Nota: En el ejemplo siguiente se supone que la página de códigos del equipo cliente es coreano (CP949) y que la página de códigos de la base de datos de SQL Server es inglés (CP1252). Debe reemplazar los marcadores de posición en los ejemplos de código con valores que son apropiados para su situación.

Para evitar este problema, siga estos pasos:
  1. Convertir manualmente los caracteres a datos sin formato y, a continuación, insertar los datos en la base de datos mediante la página de código de la base de datos. Para ello, utilice código similar al ejemplo de código siguiente.
    string strsrc="가";string strsrc="가";
    string strtag=Encoding.GetEncoding(1252).GetString(Encoding.GetEncoding(949).GetBytes (strsrc));
    sql="insert into <tablename> (<column>,) values ('" + strtag + "')";
    // code for updating the database;
    Nota: Este ejemplo de código se escribe en C#.
  2. Cuando desea consultar los datos, utilice el proveedor Microsoft OLE DB para SQL Server o el proveedor de datos de Microsoft.NET Framework para SQL Server para conectarse a la base de datos y, a continuación, establezca el parámetro Traducir automáticamente en False. Para ello, utilice código similar al ejemplo de código siguiente.
    OleDbConnection conn=new OleDbConnection("Provider=SQLOLEDB;" +
    " Initial Catalog =<yourdatabase>;"+
    "User id=<youruserid>; Password=<yourpassword>;"+
    "Auto Translate=False"
    );
    // code for representing the character data;

Estado


Microsoft ha confirmado que se trata de un problema de los productos de Microsoft que se enumeran en la sección "Aplicable a".

Más información


Pasos para reproducir el problema

  1. En el equipo cliente que tiene coreano (CP949) como la página de códigos predeterminada, inicie SQL Server Management Studio.
  2. Conectarse a una base de datos que tiene el inglés (CP1252) como la página de códigos predeterminada.
  3. Crear una tabla en la base de datos mediante la siguiente línea de código.
    Create table tbTest (A char(20), NA nchar(10), Comment char(20))
  4. Insertar un carácter coreano a la base de datos mediante la consulta siguiente.
    Insert into tbTest (A,NA,Comment) values('가',N'가','SQL2005/INSERT')
  5. Crear una consulta select para recuperar los datos mediante la siguiente línea de código.
    select * from tbTest
Recibirá los siguientes resultados. El valor de la columna A es un signo de interrogación.
A                    NA         Comment
-------------------- ---------- --------------------
? 가 SQL2005/INSERT

Referencias


Para obtener más información acerca de la intercalación de SQL Server y el parámetro de traducción automática, haga clic en los números de artículo siguientes para verlos en Microsoft Knowledge Base:
162367 cómo transferir caracteres coreano Double Byte Character Set

234748 no se puede convertir correctamente datos de caracteres desde un cliente a un servidor utilizando el controlador ODBC de SQL Server si la página de códigos cliente difiere de la página de códigos del servidor

Para obtener más información acerca de los tipos de datos Unicode de SQL Server, visite el siguiente sitio Web de Microsoft Developer Network (MSDN):