次の方法で共有


クライアント コンピューターのコード ページがデータベースのコード ページと異なる場合、文字データが正しく表されない

元の製品バージョン: SQL Server
元の KB 番号: 904803

現象

以下のシナリオについて考えてみます。

  • SQL Server Management Studio を使用して、Unicode 以外のデータ型を使用する SQL Server データベースの文字データに対してクエリを実行します。 たとえば、SQL Server データベースでは、 charvarchar、または text データ型が使用されます。

  • クライアント コンピューターのコード ページは、データベースのコード ページとは異なります。 コード ページは、データベースの照合順序に関連付けられています。

このシナリオでは、文字データが正しく表されていません。

たとえば、次のいずれかの問題が発生する可能性があります。

  • 文字データは疑問符 (?) として表されます。 文字データのクエリを実行する前に、文字データを Unicode 以外のデータ型として挿入または更新すると、この問題が発生する可能性があります。 この問題は、別のコード ページを持つクライアント コンピューターで SQL Server Management Studio を使用してこの変更を行った場合に発生します。

  • 文字データは破損データとして表されます。 コード ページ X の文字データは、コード ページ Y の Unicode 以外の列に格納されます。さらに、文字データは変換されません。 この問題は、SQL Server Management Studio を使用して文字データにクエリを実行するときに発生します。

    Note

    SQL Server Management Studio を使用して文字データのクエリを実行すると、文字データの Perform 変換 設定 ( Auto Translate パラメーターとも呼ばれます) が無効になっている場合、文字データが正しく表されます。 Auto Translate パラメーターは、Microsoft OLE DB Provider for SQL Server および Microsoft .NET Framework Data Provider for OLE DB のConnectionString プロパティのパラメーターです。

原因

この問題は、コード ページ X の文字データが、サポートされていないコード ページ Y の Unicode 以外の列に格納されているために発生します。

SQL Server では、Unicode 以外のデータ型の文字列リテラルを使用すると、データベースの照合順序から派生したデータベースの既定のコード ページを使用して文字列リテラルが変換されます。 コード ページ X の文字データをコード ページ Y の列に格納すると、データが失われたり、データが破損したりする可能性があります。

文字データが破損したデータとして表されている場合、データを正しく表すことができるのは、Microsoft OLE DB Provider for SQL Server または Microsoft .NET Framework Data Provider for OLE DB の Auto Translate パラメーターを無効にした場合のみです。

Note

SQL Server Management Studio では、Microsoft .NET Framework Data Provider for SQL Server を使用して SQL Server データベースに接続します。 このデータ プロバイダーは、 Auto Translate パラメーターをサポートしていません。

回避策

この問題を回避するには、次のいずれかの方法を使用します。

方法 1: Unicode 以外のデータ型の代わりに Unicode データ型を使用する

コード ページ変換によって発生するすべての問題を回避するために、列を Unicode データ型に変更します。 たとえば、 ncharnvarchar、または ntext データ型を使用します。

方法 2: データベースに適切な照合順序を使用する

Unicode 以外のデータ型を使用する必要がある場合は、常に、データベースのコード ページと Unicode 以外の列のコード ページが Unicode 以外のデータを正しく格納できることを確認してください。 たとえば、コード ページ 949 (韓国語) の文字データを格納する場合は、データベースに韓国語の照合順序を使用します。 たとえば、データベースの Korean_Wansung_CI_AS 照合順序を使用します。

方法 3: "binary" または "varbinary" データ型を使用する

適切なコード ページ変換を実行せずに処理される文字の正確なバイト値をデータベースに直接格納して取得する場合は、 binary または varbinary データ型を使用します。

方法 4: 別のツールを使用してデータを格納および取得し、"Auto Translate" パラメーターを無効にする

警告

コード ページ X の文字データをコード ページ Y の列に格納することはテストもサポートもしていません。この操作により、言語的に不適切なクエリ結果、不適切な文字列の一致または順序付け、予期しないコード ページ変換 (データの破損) が発生する可能性があります。 この問題を回避するには、他のいずれかの方法を使用することをお勧めします。

Microsoft OLE DB Provider for SQL Server を使用して、別のコード ページを持つデータベースに接続し、Unicode 以外のデータ型の列から文字データのクエリを実行する場合は、変換されていない文字をデータベースに格納してください。

Note

次の例では、クライアント コンピューターのコード ページが韓国語 (CP949) であり、SQL Server データベースのコード ページが英語 (CP1252) であることを前提としています。 コード例のプレースホルダーは、実際の状況に適した値に置き換える必要があります。

この問題を回避するには、次の手順を実行します。

  1. 文字を生データに手動で変換し、データベースのコード ページを使用してデータベースにデータを挿入します。 この操作を行うには、次のようなコード スニペットを使用します。

    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. データのクエリを実行する場合は、Microsoft OLE DB Provider for SQL Server または Microsoft .NET Framework Data Provider for SQL Server を使用してデータベースに接続し、 Auto Translate パラメーターを False に設定します。 この操作を行うには、次のようなコード スニペットを使用します。

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

詳細

問題を再現するには、次の手順に従います。

  1. 既定のコード ページとして韓国語 (CP949) が設定されているクライアント コンピューターで、SQL Server Management Studio を起動します。

  2. 既定のコード ページとして英語 (CP1252) が設定されているデータベースに接続します。

  3. 次のクエリを使用して、データベースにテーブルを作成します。

    CREATE TABLE tbTest (A char(20), NA nchar(10), Comment char(20))
    
  4. 次のクエリを使用して、韓国語文字をデータベースに挿入します。

    INSERT INTO tbTest (A,NA,Comment) VALUES('가',N'가','SQLServer/INSERT')
    
  5. 次のクエリを使用して、データを取得する選択クエリを作成します。

    SELECT * FROM tbTest
    

次の結果が表示されます。 列 A の値は疑問符です。


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

関連情報