クライアント コード ページがサーバー コード ページと異なる場合、SQL Server ODBC ドライバーを使用して、クライアントからサーバーに文字データを正しく変換できない

この記事では、ODBC ドライバーを使用するときにクライアント データの誤った変換が発生する問題SQL Server回避するのに役立ちます。

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

現象

MDAC 2.1 以降のバージョンの SQL Server ODBC ドライバー (バージョン 3.70.0623 以降) または OLEDB プロバイダー (バージョン 7.01.0623 以降) を使用する場合、場合によっては、接続が無効になっている場合でも、クライアント コード ページからサーバー コード ページへの文字データの変換がAutotranslation発生することがあります。

原因

Autotranslation は、コード ページ変換につながる唯一のメカニズムではありません。 SQL Server 7.0 ODBC ドライバーと OLEDB プロバイダーは、MSDE 1.0、SQL Server 7.0 以降のバージョンのいずれかに接続するときに、新しい動作を導入します。 言語イベントとして送信されるすべての SQL ステートメントは、サーバーに送信される前にクライアント上の Unicode に変換されます。 終了効果は、接続の現在Autotranslationの設定に関係なく、言語イベントを介してクライアントからサーバーにフローするすべてのデータの と似ていますAutotranslation。 SQL Serverのコード ページ以外のコード ページから翻訳されていない文字データを格納する場合を除き、問題は発生しません。

回避策

コード ページ Y SQL Serverにコード ページ X データを格納しないでください (コード ページ 1252 サーバーのコード ページ 950 データなど)。 以前のバージョンのSQL Serverでは、これは一部の状況で可能でしたが、常にサポートされていませんでした。 1252 SQL Serverでは、1252 文字以外は有効な文字データではありません。 別のコード ページの Unicode 以外の文字データは正しく並べ替えされず、デュアル バイト (DBCS) データの場合、SQL Serverは文字境界を正しく認識しません。 これは、重大な問題を引き起こす可能性があります。

SQL Serverのコード ページに最適な選択は、サーバーにアクセスするクライアントのコード ページです。

サーバーとクライアントのコード ページは異なる場合がありますが、すべてのケースでサーバーのコード ページとの間でデータを適切に翻訳できるように、クライアントで自動変換が有効になっていることを確認する必要があります。

サーバーが複数のコード ページのデータを格納する必要がある場合、サポートされている解決策は、データを Unicode 列 (NCHAR/NVARCHAR/NTEXT) に格納することです。

状況でコード ページ X データをコード ページ Y SQL Serverに格納する必要がある場合、これを確実に行うには次の 2 つの方法しかありません。

  • バイナリ列 (BINARY/VARBINARY/IMAGE) 列にデータを格納します。
  • 文字データを処理するすべての SQL ステートメントにリモート プロシージャ コール (RPC) を使用するようにアプリケーションを記述します。 RPC イベントを介して送信されたデータは、変換の対象になりません。 ドライバーレベルまたは DSN レベルでは、送信されるイベントの種類を変更するためにできることは何もありません。 コマンドが言語または RPC イベントとして送信されるかどうかは、アプリケーションの作成時にプログラマが選択した API と構文によって完全に異なります。

詳細

自動変換 (つまり、新しい ODBC アプリケーションの 文字データの変換の実行 チェック ボックス) は、Unicode を翻訳メディアとして使用して、データをサーバーに送信する前に、クライアント コード ページからサーバー コード ページに文字データを変換します。 ただし、3.7 SQL Server ODBC ドライバーは、言語イベントとして送信されたすべての SQL ステートメントを Unicode に変換してからワイヤに配置します。これは、オートトランスレーションに似ていますが、オートトランスレーション設定によって制御されません。 これに対し、サーバーからクライアントに戻る文字データは、自動変換フラグを尊重します。自動変換がオフになっている場合、データは、サーバー上のデータと同じ文字コードを使用してクライアント アプリケーションに到着します。 同様に、クライアントとサーバーの RPC イベントのデータの変換は、自動変換をオフにすることで無効にすることができます。 動作が言語イベントにどのように影響するかを示す単純なスクリプトが続きます。 この例は、コード ページ 437 サーバーに接続するコード ページ 1252 クライアントで Query Analyzer から実行されました。

-- Turn Autotranslation off here.
 USE tempdb
 GO
 CREATE TABLE t1 (c1 int, c2 char(1))
 GO

-- Enter a yen character, using the keystroke ALT-0165.
 INSERT INTO t1 VALUES (1, '¥') 
 SELECT c1, c2, ASCII (c2) FROM t1
c1 c2 
 ----------- ---- ----------- 
 1  157

(1 row(s) affected)

前の例について次に示します。

  • Autotranslationこのバッチ中はオフでしたが、文字コード 165 (コード ページ 1252 の円) は 157 (コード ページ 437 では円) に変換されました。 これは、ODBC ドライバーがサーバーを送信する前に SQL 文字列を Unicode に変換したため、サーバーはコード ページ 437 のストレージに適した文字に変換できたためです。
  • クライアントが SELECT を実行して保存されたデータを取得すると、文字 157 がクライアントに翻訳されなくなった (157 はコード ページ 1252 クライアントのボックス '' として表示されます)。 これは、この記事で説明する変換は、サーバーからクライアントに送信されるデータではなく、クライアントからサーバーに送信されるデータにのみ適用されるためです。 設定がオフになっているため、 Autotranslation データは変換されませんでした。
-- Turn Autotranslation back on before running the following batch.
 INSERT INTO t1 VALUES (2, '¥')
 SELECT c1, c2, ASCII (c2) FROM t1
c1 c2 
 ----------- ---- ----------- 
 1 ¥ 157
 2 ¥ 157

(2 row(s) affected)

この場合、オンに戻しても Autotranslation 、クライアントからサーバーへの変換には影響しませんでした (つまり、文字コード 165 から文字コード 157 への同じ正しい変換が発生しました) が、サーバーから取得されたデータに影響を与えました。 今回 SELECT ステートメントを実行すると ( Autotranslation オン)、円記号は、文字コード 157 からメカニズムによって Autotranslation 文字コード 165 に変換されているため、コード ページ 1252 アプリケーションで正しく表示されます。

SQL SERVER ODBC ドライバー バージョン 3.70 以降を使用し、SQL Server 7.0 以降に接続すると、この動作 (クライアント上の言語イベントから Unicode への変換) が表示されます。 古い ODBC ドライバーを使用している場合、または 3.7 ドライバーを使用して 6.5 以前SQL Server接続する場合は発生しません。 さらに、データを Unicode 列 (NCHAR/NVARCHAR/NTEXT) に格納する場合、変換は問題になりません。

SQL Server 2005 で文字データがどのように表されるかの詳細については、「2005 年SQL Serverのデータベースのコード ページとクライアント コンピューターのコード ページが異なる場合に文字データが正しく表されない」を参照してください。