Los datos de caracteres se representan incorrectamente cuando la página de códigos del equipo cliente difiere de la de la base de datos.

Versión del producto original: SQL Server
Número de KB original: 904803

Síntomas

Imagine la siguiente situación:

  • Use SQL Server Management Studio para consultar datos de caracteres de una base de datos de SQL Server que use un tipo de datos que no sea Unicode. Por ejemplo, la base de datos SQL Server usa el chartipo de datos , varcharo text .

  • 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 está asociada a la intercalación de la base de datos.

En este escenario, los datos de caracteres se representan incorrectamente.

Por ejemplo, puede experimentar uno de los siguientes problemas:

  • Los datos de caracteres se representan como un signo de interrogación (?). Es posible que vea este problema si inserta o actualiza 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 mediante SQL Server Management Studio en un equipo cliente que tiene una página de códigos diferente.

  • Los datos de caracteres se representan como datos dañados. Los datos de caracteres de la 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 cuando se consultan los datos de caracteres mediante SQL Server Management Studio.

    Nota:

    Al consultar los datos de caracteres mediante SQL Server Management Studio, los datos de caracteres se representan correctamente si la opción Realizar traducción de datos de caracteres (también conocida como Auto Translate parámetro) está deshabilitada. El Auto Translate parámetro es un parámetro de la propiedad para el ConnectionString proveedor OLE DB de Microsoft 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 la página de códigos X se almacenan en una columna no Unicode de la página de códigos Y, que no es compatible.

En SQL Server, cuando se usa un literal de cadena de un tipo de datos que no es Unicode, el literal de cadena se convierte mediante 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 la 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 caracteres se representan como datos dañados, los datos solo se pueden representar correctamente si deshabilita el parámetro para el Auto Translate proveedor OLE DB de Microsoft para SQL Server o el proveedor de datos de Microsoft .NET Framework para OLE DB.

Nota:

SQL Server Management Studio usa el proveedor de datos de Microsoft .NET Framework para SQL Server conectarse a la base de datos de SQL Server. Este proveedor de datos no admite el Auto Translate parámetro .

Solución alternativa

Para solucionar este problema, use uno de los métodos siguientes:

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

Cambie las columnas a un tipo de datos Unicode para evitar todos los problemas causados por la traducción de páginas de códigos. Por ejemplo, use el nchartipo de datos , nvarcharo ntext .

Método 2: Usar una intercalación adecuada para la base de datos

Si debe usar un tipo de datos que no sea 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 cualquier columna que no sea Unicode pueda almacenar los datos no Unicode correctamente. Por ejemplo, si desea almacenar datos de caracteres de la página de códigos 949 (coreano), use una intercalación coreana para la base de datos. Por ejemplo, use la Korean_Wansung_CI_AS intercalación para la base de datos.

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

Si desea que la base de datos almacene y recupere directamente los valores de bytes exactos de los caracteres que se controlan sin intentar realizar la traducción de página de códigos adecuada, use el binary tipo de datos o varbinary .

Método 4: Usar una herramienta diferente para almacenar y recuperar datos y deshabilitar el parámetro "Traducción automática"

Advertencia

No se prueba ni se admite el almacenamiento de los datos de caracteres de la página de códigos X en una columna de la página de códigos Y. Esta operación puede provocar resultados de consulta lingüísticamente incorrectos, coincidencia o ordenación de cadenas incorrectas y traducción inesperada de páginas de códigos (daños en los datos). Le recomendamos que use uno de los otros métodos para solucionar este problema.

Cuando use el proveedor OLE DB de Microsoft para SQL Server para conectarse a una base de datos que tenga una página de códigos diferente e intente consultar datos de caracteres desde una columna de tipo de datos no Unicode, asegúrese de almacenar los caracteres sin traducir en 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 de los ejemplos de código por valores adecuados para su situación.

Para resolver este problema, siga los siguientes pasos:

  1. Convierta manualmente los caracteres en datos sin procesar y, a continuación, inserte los datos en la base de datos mediante la página de códigos de la base de datos. Para realizar esta operación, use un fragmento de código similar al 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;
    
  2. Cuando desee consultar los datos, use proveedor OLE DB de Microsoft para SQL Server o proveedor de datos de Microsoft .NET Framework para SQL Server conectarse a la base de datos y, a continuación, establezca el Auto Translate parámetro en False. Para realizar esta operación, use un fragmento de código similar al siguiente:

    OleDbConnection conn=new OleDbConnection("Provider=SQLOLEDB;" +
    " Initial Catalog =<yourdatabase>;"+
    "User id=<youruserid>; Password=<yourpassword>;"+
    "Auto Translate=False");
    // code for representing the character data;
    

Más información

Para reproducir el problema, siga estos pasos:

  1. En el equipo cliente que tiene coreano (CP949) como página de códigos predeterminada, inicie SQL Server Management Studio.

  2. Conéctese a una base de datos que tenga inglés (CP1252) como página de códigos predeterminada.

  3. Cree una tabla en la base de datos mediante la consulta siguiente:

    CREATE TABLE tbTest (A char(20), NA nchar(10), Comment char(20))
    
  4. Inserte un carácter coreano en la base de datos mediante la consulta siguiente:

    INSERT INTO tbTest (A,NA,Comment) VALUES('가',N'가','SQLServer/INSERT')
    
  5. Cree una consulta select para recuperar los datos mediante la consulta siguiente:

    SELECT * FROM tbTest
    

Recibirá los siguientes resultados. El valor de la columna A es un signo de interrogación.


A                    NA         Comment
-------------------- ---------- --------------------
?                    가          SQLServer/INSERT

Referencias