none
リンクサーバーのテーブルの文字列カラムへのクエリについて RRS feed

  • 質問

  • リンクサーバー上のテーブルのvarchar型カラムは、sqlserver側でnvarchar型にマッピングされているようですが、このカラムをwhere条件とした「where [カラム名]='条件'」のようなクエリを行うと、DB2には「where [カラム名]=G'条件'」というリモートクエリを行うため、ドライバがリモートクエリに対応できず結果を取得することができません。

    nvarcharではなくvarcharにマッピングする、Gを付けないリモートクエリを作成する等の対応方法を探してみましたが、見つからないため対応方法等ご存知でしたらご享受願えますでしょうか?ヒントだけでも構いません。また、Gの正体についてもご教授いただけると助かります

    環境

    SQLSERVERのver:2012express

    リンクサーバーに使用したドライバ:microsoft ole db provider for db2 と ibm ole db provider for db2 で確認

    試したこと

    ・無理やりnvarcharをvarcharへcastしたviewを作成すると正常な結果を得ることができます。

    ・openquery([サーバー], select * from [テーブル] where [カラム名]='条件')では正常な結果を得ることができます。

    どうぞ、よろしくお願いします。

    2015年8月10日 4:36

すべての返信

  • 経験はないのですが、sp_serveroptionにて照合順序の設定を行ってはどうでしょうか?
    2015年8月10日 5:20
  • sp_serveroptionの設定は以下4パターンを試しておりますが、いずれも同様の結果でした。

    ①「照合順序互換=true;リモート照合順序を使用=true;照合順序名=null」

    ②「照合順序互換=true;リモート照合順序を使用=false;照合順序名=null」

    ③「照合順序互換=false;リモート照合順序を使用=true;照合順序名=Japanese_CI_AS」

    ④「照合順序互換=false;リモート照合順序を使用=false;照合順序名=Japanese_CI_AS」

    照合順序に関する知識が浅いため自信がありませんが、設定方法等に問題があるのでしょうか?もしよろしければ、ご指摘いただけると助かります。

    文字コード関係の環境

    リンクサーバー先のdb2のコードページ=IBM-943(Shift-Jis)

    sqlserverの規定の照合順序=Japanese_CI_AS

    2015年8月11日 0:11
  • DB2の経験はないのですが、以下を読むとGプレフィックスはNプレフィックスと同じようで、2バイト文字で処理するように指示するもののようです。

    IZ28702: WITH THE PREFIX G OR N FOR CHARACTER LITERAL, THE PARSER DOES NOT ACCOUNT FOR ESCAPE CHARACTER (').
    http://www-01.ibm.com/support/docview.wss?uid=swg1IZ28702

    ところでエラーメッセージのようなものは出ているのでしょうか? GプレフィックスはDB2でサポートされているものですから問題ないように思いますが、ドライバーのバージョンとDB2のバージョンの問題なのでしょうか?
    それともnvarcharにマッピングされたことにより、SQL ServerでNプレフィックスが付き、それをGプレフィックスにコンバートするような動きをし、それをSQL Server側を通る時にエラーになっているのでしょうか?
    この辺りが私はわかっていないのですが、例えば以下の2つを試してみるとどうなるでしょうか?

    1.最初からNプレフィックスを付けてSQLを発行する。

    2.nvarcharをvarcharに変換するSQLを書く。例えば、select convert(varchar(50), カラム名), ・・・


    ★良い回答には回答済みマークを付けよう! MVP - .NET  http://d.hatena.ne.jp/trapemiya/

    • 編集済み trapemiya 2015年8月11日 4:56 誤字修正
    2015年8月11日 4:47
  • 助言ありがとうございます。

    slserverに以下SQLを実行

    select * from TEST02.DB.スキーマ.SAMPLEVIEW where 文字列カラム='05785405';

    エラーメッセージは以下です。

    リンク サーバー "TEST02" の OLE DB プロバイダー "IBMDADB2.DB2COPY1" から、メッセージ "[DB2/NT64] SQL0401N  演算 "=" のオペランドのデータ・タイプが非互換または比較不能です。  SQLSTATE=42818
    " が返されました。
    メッセージ 7320、レベル 16、状態 2、行 1
    リンク サーバー "TEST02" の OLE DB プロバイダー "IBMDADB2.DB2COPY1" に対するクエリ "SELECT "Tbl1002"."文字列カラム" "Col1004","Tbl1002"."C02" "Col1005","Tbl1002"."C03" "Col1006" FROM "DB"."スキーマ"."SAMPLEVIEW" "Tbl1002" WHERE "Tbl1002"."文字列カラム"=G'05785405'" を実行できません。

    ご指摘いただきくまで「SQL中に不明な文字列が存在する」エラーであると思い込んでいましたが、「型の不一致」によるエラーであることに気づきました。リンクの方も拝見させていただき、Gプレフィックスによってgraphic型なるものと比較しようとしていることがわかりました。

    従ってこのviewの文字列カラムをgraphic型へ変更しselect * from TEST02.DB.スキーマ.SAMPLEVIEW where 文字列カラム=N'05785405';上記のエラーは発生しなくなりました。これは有効な解決策になるかもしれません。

    ご提示頂きました課題2つについて

    1.最初からNプレフィックスを付けてSQLを発行する。

    Nプレフィックスをつけた場合と付けない場合で同じエラーメッセージでした。

    2.nvarcharをvarcharに変換するSQLを書く。例えば、select convert(varchar(50), カラム名), ・・・

    これは最初の質問のVIEWの内容と同じかと思いますがエラーは発生せず正常動作します。ただしSQLの推定実行プランによると、リンクサーバー元のデータを全件取得した後sqlserver側でwhereが行われているようで、DB2側ではwhere=G'文字列'の処理を行っていないためエラーが発生しないと思われます。

    「GがついてもDB2側でエラーにならない方法」は目処が経ちましたが、「GをつけないSQLをDB2に送る方法」が本命であるため、解決策、若しくはヒント等を助言いただけると助かります。

    2015年8月11日 9:41