現在オフラインです。再接続するためにインターネットの接続を待っています

PRB: SQL Server ODBC ドライバで言語イベントが Unicode に変換される

この記事は、以前は次の ID で公開されていました: JP234748
現象
MDAC 2.1 または SQL Server ODBC ドライバ (バージョン 3.70.0623 以降) または OLEDB プロバイダ (バージョン 7.01.0623 以降) を使用している場合、接続に対して自動変換を無効にしているときでも、状況によってはクライアントのコード ページからサーバーのコード ページへ文字データの変換が行われる場合があります。
原因
自動変換だけが、コード ページ変換を発生させるメカニズムではありません。SQL Server 7.0 の ODBC ドライバと OLEDB プロバイダでは、MSDE 1.0、SQL Server 7.0、またはこれら以降のバージョンに接続するときの新しい動作が導入されています。言語イベントとして送信されるすべての SQL ステートメントは、サーバーへの送信前にクライアント上で Unicode に変換されます。この結果として、接続に対する現在の自動変換の設定に関係なく、言語イベントを通じてクライアントからサーバーへ送られるデータすべてで自動変換が行われることになります。SQL Server 側のコード ページ以外のコード ページから非変換の文字データを格納しようとする場合を除き、これが問題を引き起こすことはありません。
回避策
コード ページ X のデータをコード ページ Y の SQL Server に (たとえば、コード ページ 950 のデータをコード ページ 1252 のサーバに) 格納しないでください。SQL Server の前のバージョンでは、状況によってはこれが可能でしたが、サポートされていたわけではありません。コード ページ 1252 の SQL Server においては、コード ページ 1252 にある文字以外は有効な文字データではありません。異なるコード ページからの Unicode 以外の文字データは、正しく格納できません。ダブル バイト (DBCS) データの場合は、SQL Server によって文字境界が正しく認識されません。これは、Microsoft Knowledge Base の次の記事で説明されているような、重大な問題を引き起こす可能性があります。
155723INF: SQL Server Truncation of a DBCS String
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 のクライアント上のクエリ アナライザから実行されたものです。

    -- ここで自動変換をオフにします。    USE tempdb    GO    CREATE TABLE t1 (c1 int, c2 char(1))    GO    -- キーストローク ALT-0165 を使用して、円記号を入力します。    INSERT INTO t1 VALUES (1, '\')    SELECT c1, c2, ASCII (c2) FROM t1
  •         c1          c2        ----------- ---- -----------        1           ?    157        (1 件処理されました)

上記の例について、次の点に注意してください。

  • このバッチの際、自動変換はオフになっていたにもかかわらず、文字コード 165 (コード ページ 1252 の円記号) が 157 (コード ページ 437 の円記号) に変換されました。これは、ODBC ドライバが SQL 文字列をサーバーへの送信前に Unicode に変換したためであり、したがってサーバーは、その文字をコード ページ 437 の該当する文字に変換して保存することができました。
  • クライアントで SELECT を実行し、いま格納されたデータを取得すると、非変換の文字 157 がクライアントに届きます (コード ページ 1252 のクライアントでは、157 がボックス記号として表示されます)。この記事で説明した変換が、クライアントからサーバーへのデータにのみ適用され、サーバーからクライアントへのデータには適用されないことによります。自動変換の設定がオフになっているため、データは変換されませんでした。

    -- 次のバッチを実行する前に自動変換をオンに戻します。    INSERT INTO t1 VALUES (2, '\')    SELECT c1, c2, ASCII (c2) FROM t1
        c1          c2        ----------- ---- -----------        1           \    157        2           \    157        (2 件処理されました)
この場合、自動変換をオンに戻しても、クライアントからサーバーへの変換に関しては変わりありません (つまり、文字コード 165 から文字コード 157 への正しい変換が同様に行われる)。ただし、この指定はサーバーから取得されるデータに対しても有効です。この状態で (自動変換をオンにして) SELECT ステートメントを実行すると、円記号が自動変換のメカニズムにより文字コード 157 から元の文字コード 165 に変換されるため、コード ページ 1252 のアプリケーションで正しく表示される点に注目してください。

SQL Server ODBC ドライバのバージョン 3.70 以上を使用して SQL Server 7.0 以上に接続すると、この動作 (言語イベントがクライアント上で Unicode に変換される現象) が見られます。これよりも古い ODBC ドライバを使用している場合や、バージョン 3.7 のドライバを使用して SQL Server 6.5 以前に接続する場合は、この現象は発生しません。さらに、Unicode 列 (NCHAR/NVARCHAR/NTEXT) にデータを格納する場合、この変換は問題になりません。
詳細
この資料は米国 Microsoft Corporation から提供されている Knowledge Base の Article ID 234748(最終更新日 2000-02-21) をもとに作成したものです。

プロパティ

文書番号:234748 - 最終更新日: 09/28/2004 04:07:00 - リビジョン: 1.0

Microsoft SQL Server 7.0 Standard Edition

  • kbtshoot kbsqlserv700 KB234748
フィードバック
/html>