SAP SQL Anywhere のプロキシーテーブルにおける制限/仕様 (過去のブログ記事より)
このページは、以下の英語ページの抄訳です。最新の情報については、英語ページを参照してください。
この記事のオリジナルは、Glenn Paulley が sybase.com に 2012 年 3 月に掲載したものです。Glenn はこの記事で SQL Anywhere のリモートデータアクセス機能に関連する制限について解説しています。
===
プロキシーテーブルは、リモートデータアクセスまたは OMNIと呼ばれることもありますが、全て同じ接続から異なるデータベースのテーブルにクエリを実行したり変更したりするのに便利な方法です。
SQL Anywhere のプロキシーテーブルは、ゆるく一対となるマルチデータベースシステムの実装です。基本となるデータベースは、SQL Anywhereである必要はなく、ODBCをサポートするデータソースであれば、何でも構いません。そのため、基本となるプロキシーのベースのテーブルは、Oracle のテーブルでも、Microsoft SQL Server のテーブルでも、あるいは Excel でも構いません。
プロキシーテーブルのスキーマをデータベースのカタログ内に定義すれば、そのテーブルはその他のテーブルと同様にそのデータベース内のローカルテーブルとして定義されているかのようにクエリを実行することができます。
これが全体概念ですが、これの実装にはいくつかの注意点があります。特にその中の一つについてここで説明したいと思います。これは、長くSQL Anywhere を使用されているお客様、Frank Vestjens 氏が(旧)NNTP ニュースグループ sybase.public.sqlanywhere.general に以下のSQL バッチについて質問されたことがきっかけです。
- begin
- declare dd date;
- declare tt time;
- declareresultaatnumeric;
- //
- set dd = ‘2012-06-07’;
- set tt = ’15:45:00.000′;
- //
- message dd + tt type info to console;
- //
- select first Id into resultaat
- from p_mmptankplanning
- where arrivalDate + IsNull(arrivaltime,’00:00:00′) <= dd+tt
- order by arrivaldate+arrivalTime,departuredate+departureTime;
- end
このバッチは、ローカルテーブル p_mmptankplanning
ではうまく機能しますが、テーブルがプロキシーテーブルである場合にはエラーになります。エラーは “Cannot convert 2012-06-0715:45:00.000 to a timestamp” となります。
演算子のオーバーロード
SQL Anywhere では、マルチデータベースのリクエストは、ODBC 接続で基本となるデータソースに送信される SQL 文に分解されます。多くの場合、完全な SQL 文は、送信元サーバーには後処理は必要ないため、「フルパススルーモード」と呼ぶ、基本となるサーバーに送信されます。サーバーは、そのクエリを基本となる DBMS に送信し、データベースシステムは結果セットを返してクライアントにパーコレートされます。送信元サーバーは SQL Anywhere なので、オリジナルのステートメントの SQL 方言は、SQL Anywhere で理解できる必要があります。
基本となる DBMS が SQL Anywhere ではない場合、そのサーバーのリモートデータアクセスのサポートは、ステートメントに対して何らかのマイナーな構文的な変更をするかもしれません。あるいは、基本となるサーバーに欠けている機能を補うような試みをするかもしれません。
DBMS に送信される SQL 文は、フルパススルーモードで処理されるか部分的なパススルーモードで処理されるかにかかわらず、string です。また SQL Anywhere は、SELECT、
INSERT、
UPDATE、
DELETE、
MERGE
文を基本となる DBMS に送信することができます。しかしながら、バッチまたはプロシージャー定義を送信する機能はありません。
そのため、上記のクエリにおける問題は、クエリが date/time 変数の dd
と tt
を参照し、演算子 +
を TIMESTAMP
に結合するために使用してしまうことです。SQL Anywhere には SQL バッチを送信する機能がないため、基本となる DBMS サーバーに送信されるのは、SQL 文になります。
- select first Id into resultaat
- from p_mmptankplanning
- where arrivalDate + IsNull(arrivaltime,’00:00:00′) <= ‘2012-06-07’ + ’15:45:00.000′
- order by arrivaldate+arrivalTime,departuredate+departureTime;
ここでは問題は、さらに明白です。SQL Anywhere では、’+’ 演算子は date/time タイプの演算子と strings の両方をサポートするためにオーバーロードになってしまいます。stringでは、’+’ は string 連結です。上記のステートメントが、基本となる SQL Anywhere サーバーに送信されると、二つの date/time string を連結し、string ‘2012-06-0715:45:00.000’ を形成します。ブランクは入らないことに注意してください。そして、これが、直接コンバージョンエラーに結びつくことになります。SQL バッチの堅牢なサポートがあれば、この問題は解決されますが、現在計画はありません。ワークアラウンドとしては、好ましい TIMESTAMP
をクエリの外部に構成して、コンバートされた時に基本となるクエリが好ましいセマンティクスをあたえるようにします。
しかしながら、その場合でも、DATE_ORDER
と DATEFORMAT
オプション設定が関連するサーバーにわたって確実に互換であるように留意する必要があります。
SQL Anywhere リモートデータアクセスの内部動作について説明してくれた同僚の Karim Khamis に感謝します。
===
SAP SQL Anywhere に関する詳細情報は、SAP SQL Anywhere Communityページ<英語> を参照してください。
上記のコミュニティーに掲載されている技術情報は、順次SQL Anywhere 日本語コミュニティ
に掲載しています。
SQL Anywhere に関してはまずはこちらをご参照ください。無期限でご利用いただける無償の Developers Edition もこちらからダウンロードが可能です。
SQL Anywhere に関して技術的な質問のある方はコミュニティに登録し、
「Ask a Question」機能をご利用ください。
Language には「Japanese」、
Primary Tag には「SAP SQL Anywhere」を選択
User Tagに「sql anywhere」「sql anywhere Japanese question」
を入力してください。
不具合につきましては、サポート契約者様専用の問い合わせ方法にてお問い合わせください。
======================
ご購入に関するお問い合わせ
こちらよりお問い合わせください。