Os dados de caracteres são representados incorretamente quando a página de código do computador cliente é diferente da do banco de dados

Versão original do produto: SQL Server
Número de KB original: 904803

Sintomas

Considere o seguinte cenário:

  • Você usa SQL Server Management Studio para consultar dados de caracteres de um banco de dados SQL Server que usa um tipo de dados não Unicode. Por exemplo, o banco de dados SQL Server usa o chartipo , varcharou text de dados.

  • A página de código do computador cliente difere da página de código do banco de dados. A página de código está associada à ordenação do banco de dados.

Nesse cenário, os dados de caracteres são representados incorretamente.

Por exemplo, você pode ter um dos seguintes problemas:

  • Os dados de caracteres são representados como um ponto de interrogação (?). Você poderá ver esse problema se inserir ou atualizar os dados do caractere como um tipo de dados não Unicode antes de consultar os dados do caractere. Esse problema ocorrerá se você fizer essa alteração usando SQL Server Management Studio em um computador cliente que tenha uma página de código diferente.

  • Os dados de caracteres são representados como dados corrompidos. Os dados de caractere da página de código X são armazenados em uma coluna não Unicode da página de código Y. Além disso, os dados do caractere não são traduzidos. Esse problema ocorre quando você consulta os dados do caractere usando SQL Server Management Studio.

    Observação

    Ao consultar os dados de caractere usando SQL Server Management Studio, os dados de caracteres serão representados corretamente se a configuração Executar tradução para dados de caractere (também conhecida como Auto Translate parâmetro) estiver desabilitada. O Auto Translate parâmetro é um parâmetro da propriedade para o ConnectionString Microsoft OLE DB Provider for SQL Server e para o Microsoft .NET Framework Data Provider for OLE DB.

Motivo

Esse problema ocorre porque os dados de caractere da página de código X são armazenados em uma coluna não Unicode da página de código Y, que não tem suporte.

Em SQL Server, quando você usa um literal de cadeia de caracteres de um tipo de dados não Unicode, o literal da cadeia de caracteres é convertido usando a página de código padrão do banco de dados derivada da ordenação do banco de dados. Armazenar os dados de caractere da página de código X em uma coluna da página de código Y pode causar perda de dados ou corrupção de dados.

Se os dados de caracteres forem representados como dados corrompidos, os dados só poderão ser representados corretamente se você desabilitar o parâmetro para o Auto Translate Microsoft OLE DB Provider for SQL Server ou Microsoft .NET Framework Data Provider for OLE DB.

Observação

SQL Server Management Studio usa o Microsoft .NET Framework Data Provider para SQL Server para se conectar ao banco de dados SQL Server. Esse provedor de dados não dá suporte ao Auto Translate parâmetro.

Solução alternativa

Para contornar esse problema, use um dos seguintes métodos:

Método 1: usar um tipo de dados Unicode em vez de um tipo de dados não Unicode

Altere as colunas para um tipo de dados Unicode para evitar todos os problemas causados pela tradução de página de código. Por exemplo, use o nchartipo de dados , nvarcharou ntext .

Método 2: usar uma ordenação apropriada para o banco de dados

Se você precisar usar um tipo de dados não Unicode, certifique-se sempre de que a página de código do banco de dados e a página de código de qualquer coluna não Unicode possam armazenar os dados não Unicode corretamente. Por exemplo, se você quiser armazenar dados de caracteres da página de código 949 (coreano), use uma ordenação coreana para o banco de dados. Por exemplo, use a Korean_Wansung_CI_AS ordenação para o banco de dados.

Método 3: usar o tipo de dados "binário" ou "varbinary"

Se você quiser que o banco de dados armazene e recupere os valores exatos de bytes dos caracteres tratados sem tentar executar a tradução de página de código apropriada, use o binary tipo de dados ou varbinary .

Método 4: usar uma ferramenta diferente para armazenar e recuperar dados e desabilitar o parâmetro "Traduzir Automaticamente"

Aviso

Não testamos ou oferecemos suporte para armazenar os dados de caractere da página X de código em uma coluna da página de código Y. Essa operação pode causar resultados de consulta linguisticamente incorretos, correspondência ou ordenação de cadeia de caracteres incorreta e tradução inesperada da página de código (corrupção de dados). Recomendamos que você use um dos outros métodos para resolver esse problema.

Quando você usa o Provedor OLE DB da Microsoft para SQL Server para se conectar a um banco de dados que tem uma página de código diferente e tenta consultar dados de caracteres de uma coluna de tipo de dados não Unicode, verifique se você armazena os caracteres não traduzidos no banco de dados.

Observação

O exemplo a seguir pressupõe que a página de código do computador cliente é coreana (CP949) e que a página de código do banco de dados SQL Server é inglês (CP1252). Você deve substituir os espaços reservados nos exemplos de código por valores apropriados para sua situação.

Como solução alternativa para este problema, siga as seguintes etapas:

  1. Converta manualmente os caracteres em dados brutos e insira os dados no banco de dados usando a página de código do banco de dados. Para fazer essa operação, use um snippet de código semelhante ao seguinte:

    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. Quando quiser consultar os dados, use o Provedor OLE DB da Microsoft para SQL Server ou Microsoft .NET Framework Provedor de Dados para SQL Server para se conectar ao banco de dados e, em seguida, defina o Auto Translate parâmetro como False. Para fazer essa operação, use um snippet de código semelhante ao seguinte:

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

Mais informações

Para reproduzir o problema, siga estas etapas:

  1. No computador cliente que tem o coreano (CP949) como a página de código padrão, inicie SQL Server Management Studio.

  2. Conecte-se a um banco de dados que tem o inglês (CP1252) como a página de código padrão.

  3. Crie uma tabela no banco de dados usando a seguinte consulta:

    CREATE TABLE tbTest (A char(20), NA nchar(10), Comment char(20))
    
  4. Insira um caractere coreano no banco de dados usando a seguinte consulta:

    INSERT INTO tbTest (A,NA,Comment) VALUES('가',N'가','SQLServer/INSERT')
    
  5. Crie uma consulta selecionada para recuperar os dados usando a seguinte consulta:

    SELECT * FROM tbTest
    

Você recebe os resultados a seguir. O valor na coluna A é um ponto de interrogação.


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

Referências