Dela via


Teckendata representeras felaktigt när klientdatorns kodsida skiljer sig från databasens

Ursprunglig produktversion: SQL Server
Ursprungligt KB-nummer: 904803

Symptom

Föreställ dig följande scenario:

  • Du använder SQL Server Management Studio för att fråga efter teckendata från en SQL Server-databas som använder en datatyp som inte är Unicode. Sql Server-databasen använder chartill exempel datatypen , varchareller text .

  • Kodsidan på klientdatorn skiljer sig från databasens kodsida. Kodsidan är associerad med sortering av databasen.

I det här scenariot representeras teckendata felaktigt.

Du kan till exempel uppleva något av följande problem:

  • Teckendata representeras som ett frågetecken (?). Det här problemet kan uppstå om du infogar eller uppdaterar teckendata som en icke-Unicode-datatyp innan du frågar efter teckendata. Det här problemet uppstår om du gör den här ändringen med hjälp av SQL Server Management Studio på en klientdator som har en annan kodsida.

  • Teckendata representeras som skadade data. Teckendata för kodsidan X lagras i en icke-Unicode-kolumn på kodsidan Y. Dessutom översätts inte teckendata. Det här problemet uppstår när du frågar efter teckendata med hjälp av SQL Server Management Studio.

    Kommentar

    När du kör frågor mot teckendata med hjälp av SQL Server Management Studio representeras teckendata korrekt om inställningen Utför översättning för teckendata (kallas även parametern Auto Translate ) är inaktiverad. Parametern Auto Translate är en parameter för ConnectionString egenskapen för Microsoft OLE DB-providern för SQL Server och för Microsoft .NET Framework Data Provider för OLE DB.

Orsak

Det här problemet beror på att teckendata på kodsidan X lagras i en icke-Unicode-kolumn på kodsidan Y, som inte stöds.

När du använder en strängliteral av en icke-Unicode-datatyp i SQL Server konverteras strängliteralen med hjälp av databasens standardkodsida som härleds från databasens sortering. Om teckendata lagras på kodsidan X i en kolumn på kodsidan Y kan data gå förlorade eller skadas.

Om teckendata representeras som skadade data kan data endast representeras korrekt om du inaktiverar parametern Auto Translate för Microsoft OLE DB-providern för SQL Server eller Microsoft .NET Framework Data Provider för OLE DB.

Kommentar

SQL Server Management Studio använder Microsoft .NET Framework Data Provider för SQL Server för att ansluta till SQL Server-databasen. Den här dataprovidern stöder inte parametern Auto Translate .

Lösning

Du kan undvika det här problemet genom att använda någon av följande metoder:

Metod 1: Använd en Unicode-datatyp i stället för en icke-Unicode-datatyp

Ändra kolumnerna till en Unicode-datatyp för att undvika alla problem som orsakas av kodsideöversättning. Använd till exempel nchardatatypen , nvarchareller ntext .

Metod 2: Använd en lämplig sortering för databasen

Om du måste använda en datatyp som inte är Unicode kontrollerar du alltid att kodsidan i databasen och kodsidan för alla icke-Unicode-kolumner kan lagra icke-Unicode-data korrekt. Om du till exempel vill lagra teckendata på kodsidan 949 (koreanska) använder du en koreansk sortering för databasen. Använd till exempel Korean_Wansung_CI_AS sortering för databasen.

Metod 3: Använd datatypen "binär" eller "varbinär"

Om du vill att databasen ska lagra och hämta de exakta bytevärdena för de tecken som hanteras utan att försöka utföra lämplig kodsideöversättning använder du binary datatypen eller varbinary .

Metod 4: Använd ett annat verktyg för att lagra och hämta data och inaktivera parametern "Automatisk översättning"

Varning

Vi testar eller stöder inte lagring av teckendata på kodsidan X i en kolumn på kodsidan Y. Den här åtgärden kan orsaka språkligt felaktiga frågeresultat, felaktig strängmatchning eller beställning och oväntad kodsideöversättning (skadade data). Vi rekommenderar att du använder någon av de andra metoderna för att lösa problemet.

När du använder Microsoft OLE DB-providern för SQL Server för att ansluta till en databas som har en annan kodsida och du försöker köra frågor mot teckendata från en datatypskolumn som inte är unicode, kontrollerar du att du lagrar de oöversatta tecknen i databasen.

Kommentar

I följande exempel förutsätts att kodsidan på klientdatorn är koreansk (CP949) och att kodsidan i SQL Server-databasen är engelska (CP1252). Du måste ersätta platshållarna i kodexemplen med värden som är lämpliga för din situation.

Undvik problemet så här:

  1. Konvertera tecknen till rådata manuellt och infoga sedan data i databasen med hjälp av databasens kodsida. Om du vill utföra den här åtgärden använder du ett kodfragment som liknar följande:

    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. När du vill köra frågor mot data använder du Microsoft OLE DB-providern för SQL Server eller Microsoft .NET Framework Data Provider för SQL Server för att ansluta till databasen och anger sedan parametern Auto Translate till False. Om du vill utföra den här åtgärden använder du ett kodfragment som liknar följande:

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

Mer information

Följ dessa steg för att återskapa problemet:

  1. Starta SQL Server Management Studio på den klientdator som har koreanska (CP949) som standardkodsida.

  2. Anslut till en databas som har engelska (CP1252) som standardkodsida.

  3. Skapa en tabell i databasen med hjälp av följande fråga:

    CREATE TABLE tbTest (A char(20), NA nchar(10), Comment char(20))
    
  4. Infoga ett koreanskt tecken i databasen med hjälp av följande fråga:

    INSERT INTO tbTest (A,NA,Comment) VALUES('가',N'가','SQLServer/INSERT')
    
  5. Skapa en select-fråga för att hämta data med hjälp av följande fråga:

    SELECT * FROM tbTest
    

Du får följande resultat. Värdet i kolumn A är ett frågetecken.


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

Referenser