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

文書翻訳 文書翻訳
文書番号: 234748 - 対象製品
この記事は、以前は次の 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 の 次の記事 で説明されているような、重大な問題を引き起こす可能性があります。
155723 INF: 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 - 最終更新日: 2004年9月28日 - リビジョン: 1.0
この資料は以下の製品について記述したものです。
  • Microsoft SQL Server 7.0 Standard Edition
キーワード:?
kbtshoot kbsqlserv700 KB234748
"Microsoft Knowledge Baseに含まれている情報は、いかなる保証もない現状ベースで提供されるものです。Microsoft Corporation及びその関連会社は、市場性および特定の目的への適合性を含めて、明示的にも黙示的にも、一切の保証をいたしません。さらに、Microsoft Corporation及びその関連会社は、本文書に含まれている情報の使用及び使用結果につき、正確性、真実性等、いかなる表明・保証も行ないません。Microsoft Corporation、その関連会社及びこれらの権限ある代理人による口頭または書面による一切の情報提供またはアドバイスは、保証を意味するものではなく、かつ上記免責条項の範囲を狭めるものではありません。Microsoft Corporation、その関連会社 及びこれらの者の供給者は、直接的、間接的、偶発的、結果的損害、逸失利益、懲罰的損害、または特別損害を含む全ての損害に対して、状況のいかんを問わず一切責任を負いません。(Microsoft Corporation、その関連会社 またはこれらの者の供給者がかかる損害の発生可能性を了知している場合を含みます。) 結果的損害または偶発的損害に対する責任の免除または制限を認めていない地域においては、上記制限が適用されない場合があります。なお、本文書においては、文書の体裁上の都合により製品名の表記において商標登録表示、その他の商標表示を省略している場合がありますので、予めご了解ください。"

フィードバック

 

Contact us for more help

Contact us for more help
Connect with Answer Desk for expert help.
Get more support from smallbusiness.support.microsoft.com