分散環境におけるSQLの制約
この項では、分散環境におけるSQLに対する制約について説明します。
これらの制約は、Oracle以外のシステムまたはリモートOracleデータベースへのアクセスが行われる分散環境に適用されます。
- リモート参照と異機種間参照
異機種間アクセスに関するルールの多くは、リモート参照にも適用されます。 - 分散環境でリモート・マッピングにSQLを使用する場合のルールおよび制限事項
分散環境でリモート・マッピングにSQLを使用した場合に、ルールおよび制限事項があります。
親トピック: Oracle Database Gatewayの機能
リモート参照と異機種間参照
異機種間アクセスに関するルールの多くは、リモート参照にも適用されます。
SQL文は、制限付きではありますが、そのSQL文で参照されているデータベース・ノードまたはローカル・ノード上で実行できます。参照されるオブジェクトすべてが1つの参照先ノードに解決される場合、Oracleはそのノードで問合せの実行を試みます。/*+ REMOTE_MAPPED */
または/*+ DRIVING_SITE */
ヒントを使用すると、参照先ノードで強制的に実行できます。文が発行された場所とは異なるノードに転送される場合、その文はリモート・マップされています。
リモート・マップ文に対しては、完全なデータ型チェックのサポートがあります。チェックの結果により、一貫したデータ型チェックと完全なデータ型の強制が提供されます。
SQL文をリモート・マップするには特定のルールに従う必要があります。これらのルールが遵守されていない場合、エラーが発生します。ルールが適用される順序は関係ありません。
分散環境でのリモート・マッピングにSQLを使用する場合は、異なる制約が存在します。この分散環境には、リモートのOracleデータベースと、Oracle Database Gatewayを介してアクセスされるOracle以外のデータベースを含めることができます。
関連項目:
分散データベースの詳細は、『Oracle Database管理者ガイド』を参照してください。
親トピック: 分散環境におけるSQLの制約
分散環境でリモート・マッピングにSQLを使用する場合のルールおよび制限事項
分散環境でリモート・マッピングにSQLを使用した場合に、ルールおよび制限事項があります。
次の項では、分散環境でリモート・マッピングにSQLを使用する場合に存在する様々なルールまたは制限について説明します。
注意:
以降の例では、remote_db
名詞はOracle以外のリモート・システム、remote_oracle_db
名詞はリモートのOracle Databaseを指します。
ルールA: データ定義言語文はリモート・マップできません。
Oracleのデータ定義言語では、ターゲット・オブジェクトの構文にはリモート参照の位置がありません。リモート参照を含むデータ定義言語文はローカルに実行されます。異機種間サービスの場合、これは、SQLを使用してOracle以外のデータベースにデータベース・オブジェクトを直接作成できないことを意味します。
次の例に示すように、パススルーSQLを使用してデータベース・オブジェクトを個別に作成できます。
DECLARE num_rows INTEGER; BEGIN num_rows := DBMS_HS_PASSTHROUGH.EXECUTE_IMMEDIATE@remote_db ( 'create table x1 (c1 char, c2 int)' ); END;
ルールB: リモート・ターゲット表を使用するINSERT、UPDATEおよびDELETE文はリモート・マップする必要があります。
このルールは、リモートのOracleデータベースよりもOracle以外のリモート・データベースの場合に限定的です。これは、Oracle以外のシステムの表に対するデータ操作言語(DML)文の実行中は、リモート・システムで元のOracleデータベースからデータを取得できないためです。
たとえば、ローカルのemp
表からローカルの全従業員をOracle以外のリモートのemp
表に挿入するには、次の文を使用します。
INSERT INTO emp@remote_db SELECT * FROM emp;
この文は、リモート・データベースにリモート・マップされます。リモート・データベースに送信されるリモート・マップ文には、emp
に関する元のデータベースへのリモート参照が含まれます。リモート・データベースが受信するリモート・リンクを、コールバック・リンクと呼びます。
注意:
コールバック・リンクは、汎用の異機種間サービスでサポートされていても、すべての異機種間サービス・エージェントに実装されているとはかぎりません。使用中のデータベース・ゲートウェイでコールバック・リンクが動作するかどうかは、データベース・ゲートウェイのマニュアルを参照して判断してください。
特定のゲートウェイにコールバック・リンクがサポートされていない場合、前述のINSERT
文では次のエラーが戻されます。
ORA-02025: all tables in the SQL statement must be at the remote database
このエラーを回避するには、PL/SQLブロックを記述します。次に例を示します。
DECLARE CURSOR remote_insert IS SELECT * FROM emp; BEGIN FOR rec IN remote_insert LOOP INSERT INTO emp@remote_db (empno, ename, deptno) VALUES ( rec.empno, rec.ename, rec.deptno ); END loop; END;
もう1つの特殊な事例には、USER
、USERENV
およびSYSDATE
など、セッション固有のSQL関数が関係します。これらの関数は、元のサイトで実行する必要があります。これらの関数を含むリモート・マップ文には、コールバック・リンクが含まれます。コールバックがサポートされていないOracle以外のデータベースの場合は、(デフォルトで)制限エラーになる可能性があります。
たとえば、次の文を考えてみます。
DELETE FROM emp@remote_db WHERE hiredate > sysdate;
この文は次のエラー・メッセージを戻します。
ORA-02070: database REMOTE_DB does not support special functions in this context
このエラーを解決するには、次のように特殊関数をバインド変数で置き換える必要があります。次に例を示します。
DELETE FROM emp@remote_db WHERE hiredate > :1;
ルールC: NESTED TABLE型の列、ユーザー定義型の列、不透明型の列またはREF型の列を含む表などのオブジェクト機能は、リモート・マップできません。
現在、異機種間アクセスの場合、これらの列型はサポートされていません。したがって、この制限が直接発生することはありません。
ルールD: リモート・サイトでサポートされていない演算子および構成メンバーを含むSQL文は、リモート・マップできません。
INSERT
、UPDATE
またはDELETE
文の場合、SQL文は実行できません(ルールBを参照)。ただし、サポートされていない演算子または構成メンバーが、コールバック・リンクで実行できる場合、SQL文を実行できる場合があります。
SELECT
文の場合は、その他のルールが対象の文をリモート・マップするように要求していなければ、このルールの影響を受ける文を実行できます。このルールの影響を受けるSELECT
文は、リモートのSELECT
操作を介して必要なすべてのデータを取得し、サポートされない演算子を処理するか、SQLエンジンを使用してローカルに構成することにより実行されます。
リモートのSELECT
操作とは、ローカル表データの行を取得する操作とは異なり、リモート表データの行を取得する操作です。全表スキャンでは、ネットワークを介してリモート表のすべてのデータがフィルタせずに取得されます(SELECT * FROM EMP
など)。
全表スキャンは高コストであるため、Oracle名詞は回避を試みます。リモート表に使用可能な索引がある場合は、ネットワークで取得される行の数を減らすために、これらの索引をWHERE
句の条件で使用します。
Oracle Databaseにより生成されたSQL文をチェックするには、その文を記述し、REMOTE
操作ごとにEXPLAIN PLAN表のOTHER
列を問い合せます。
関連項目:
リモート参照を含むEXPLAIN PLANを解析する方法の詳細は、「例: 索引統計と表統計の使用」を参照してください。
たとえば、次の文を考えてみます。
SELECT COUNT(*) FROM emp@remote_db WHERE hiredate < sysdate;
この文では次の出力が戻されます。
COUNT(*) ---------- 14 1 row selected.
リモート表スキャンは次のとおりです。
SELECT hiredate FROM emp;
sysdate
はremote_db
または評価ルールでサポートされていないため、フィルタに変換される条件を生成してリモート操作に渡すことはできません。そのため、sysdate
はローカルに実行する必要があります。
注意:
リモート表スキャン操作は元の問合せについては一部のみ関連するため、受信行数が予想より大幅に多くなり、パフォーマンスが大幅に低下する場合があります。
ルールE: 表の式を含むSQL文はリモート・マップできません。
異機種間アクセス・モジュールでは表の式がサポートされていないため、この制限が直接発生することはありません。
ルールF: SQL文でLONGデータが選択される場合は、その文をLONGを含む表が常駐するノードにマップする必要があります。
次のタイプの文を考えてみます。
SELECT long1 FROM table_with_long@remote_db, dual;
(コールバック・リンクがサポートされていない場合)前述の文は次のエラー・メッセージを戻します。
ORA-02025: all tables in the SQL statement must be at the remote database
ルールG: SQL文がSELECT...FOR UPDATE OF...形式の場合、その文はFOR UPDATE OF句で参照される列を持つ表が常駐するノードにマップする必要があります。
SQL文がSELECT...FOR UPDATE OF...
形式の場合、その文はFOR UPDATE OF
句で参照される列を持つ表が常駐するノードにマップする必要があります。
たとえば、次の文を考えてみます。
SELECT ename FROM emp@remote_db WHERE hiredate < sysdate FOR UPDATE OF empno;
前述の文は、リモート・マップが不可能な場合、次のエラー・メッセージを戻します。
ORA-02070: database REMOTE_DB does not support special functions in this context
ルールH: SQL文に順序が含まれている場合は、その文を各順序が存在するサイトにマップする必要があります。
リモートではOracle以外の順序はサポートされないため、このルールが異機種間アクセス・モジュールに適用されることはありません。
ルールI: 文にユーザー定義演算子が含まれている場合は、その文を各演算子が定義されているノードにマップする必要があります。
文にユーザー定義演算子が含まれている場合は、その文全体をその演算子が定義されているデータベース・ノードにリモート・マップする必要があります。
ルールJ: 重複するバインド変数を含む文はリモート・マップできません。
この制限を回避するには、一意のバインド変数を使用して数値でバインドします。
親トピック: 分散環境におけるSQLの制約