機械翻訳について

4.11 ゲートウェイを通じたネイティブSQL文の受渡し

パススルーSQL機能により、アプリケーション開発者は、Oracle Databaseによる文の解釈なしで直接DRDAサーバーにSQL文を送信できます。

ゲートウェイでサポートされているDBMS_HS_PASSTHROUGH.EXECUTE_IMMEDIATE SQLパススルー文は、非問合せ(INSERT, UPDATE, DELETEおよびDDL文)に制限され、バインド変数を含めることはできません。 ゲートウェイは、DBMS_HS_PASSTHROUGH.EXECUTE_IMMEDIATEを使用してネイティブSQL文を実行できます。

DBMS_HS_PASSTHROUGH.EXECUTE_IMMEDIATEは、組込みゲートウェイ関数です。 このファンクションは、1つの入力引数を受け取り、SQL文により影響される行の数を戻します。 データ定義言語(DDL)文の場合、このファンクションは0(ゼロ)を戻します。

DBMS_HS_PASSTHROUGH.EXECUTE_IMMEDIATEはゲートウェイの予約名で、ネイティブSQLの実行に特に使用されます。

Oracle Database Gateway for DRDAの12cリリース2 (12.2)では、パススルーで発行された問合せから結果セットを取得できます。 構文は、DBMS_HS_PASSTHROUGH.EXECUTE_IMMEDIATE関数とは異なります。 詳細は、「パススルーによる結果セットの取得」を参照してください。

4.11.1 パススルーを通じたDDL文の処理

DBMS_HS_PASSTHROUGH.EXECUTE_IMMEDIATE 関数で処理されるSQL文は、Oracleデータベースでは解釈されません。

その結果、Oracleデータベースでは、そのような文がDRDAサーバーに変更を加えているかどうかは認識されません。 つまり、DRDAサーバーへの変更後にOracleデータベースのキャッシュされた情報を最新の状態に保たないかぎり、データベースは、同じセッション内の後続の問合せで不正確または古い情報に引き続き依存する可能性があります。

この例としてあげられるのが、列の追加や削除により表の構造を変更する場合です。 アプリケーションがゲートウェイを介して表を参照する場合(問合せを実行する場合など)、Oracleデータベースは表定義をキャッシュします。 次に、同じセッション内で、DBMS_HS_PASSTHROUGH.EXECUTE_IMMEDIATEを使用して列を追加することで、アプリケーションが表のフォームを変更するとします。 次に、アプリケーションによる表への次の参照によって、表の古い列定義が返され、表の新しい列は無視されます。 これは、Oracleデータベースで文が処理されておらず、変更の知識がないためです。 データベースでは変更を認識していないため、表の形式を再度問い合せる理由はなく、すでにキャッシュされた形式を使用して新規問合せをすべて処理することになります。

Oracleデータベースで表の新しい形式を取得するには、ゲートウェイを含む既存のセッションをクローズし、新しいセッションをオープンする必要があります。 これを行うには、次の2つの方法があります。

  • Oracleデータベースを使用してアプリケーション・セッションを終了し、DRDAサーバーに変更を加えた後に新しいセッションを開始
  • DRDAサーバーに変更を加えた後に、ALTER SESSION CLOSE DATABASE LINKコマンドを実行します。

前述のいずれかのアクションによって、キャッシュされた表定義が無効になり、Oracleデータベースで次の参照に関する新しい定義が強制的に取得されます。

4.11.2 DBMS_HS_PASSTHROUGH.EXECUTE_IMMEDIATEの使用

DBMS_HS_PASSTHROUGH.EXECUTE_IMMEDIATEを使用してパススルーSQL文を実行するには、次の構文を使用します。number_of_rows は、パススルーSQL完了の影響を受ける行数が割り当てられる変数です。

たとえば:

number_of_rows = DBMS_HS_PASSTHROUGH.EXECUTE_IMMEDIATE@dblink ('native_DRDA_sql');

DDL文の場合、影響を受ける行の数として0(ゼロ)が戻されます。

dblinkは、ゲートウェイへのアクセスに使用されるデータベース・リンクの名前です。

native_DRDA_sql は、有効な非問合せSQL文です(CONNECTCOMMITおよびROLLBACKを除く)。 文にバインド変数を含めることはできません。 DRDAサーバーは、動的に準備できないネイティブSQL文を拒否します。 DBMS_HS_PASSTHROUGH.EXECUTE_IMMEDIATE関数によって渡されるSQL文は、文字列である必要があります。 有効なSQL文の詳細は、特定のDRDAサーバーのSQLリファレンスを参照してください。

4.11.2.1 サンプル

DBMS_HS_PASSTHROUGH.EXECUTE_IMMEDIATEを使用する例。

  1. DBMS_HS_PASSTHROUGH.EXECUTE_IMMEDIATEを使用して、DB2表に行を挿入します:
    DECLARE
      num_rows integer;
    BEGIN
    num_rows:=DBMS_HS_PASSTHROUGH.EXECUTE_IMMEDIATE@dblink
    ('INSERT  INTO SCOTT.DEPT VALUES (10,''PURCHASING'',''PHOENIX'')');
    END;
    /
  2. DBMS_HS_PASSTHROUGH.EXECUTE_IMMEDIATEを使用して、DB2に表を作成します:
    DECLARE
      num_rows integer;
    BEGIN
      num_rows:=DBMS_HS_PASSTHROUGH.EXECUTE_IMMEDIATE@dblink
      ('CREATE TABLE MYTABLE (COL1 INTEGER, COL2 INTEGER, COL3 CHAR(14),
      COL4 VARCHAR(13))');
    END;
    /

4.11.3 パススルーを通じた結果セットの取得

Oracle Database Gateway for DRDAは、パススルーを介して入力されたSELECT SQL文から結果セットを取得する機能を提供します。

詳細は、Oracle Database異機種間接続ユーザー・ガイドを参照してください。

4.11.3.1

DBMS_HS_PASSTHROUGHを使用した例。

DECLARE
  CRS binary_integer;
  RET binary_integer;
  VAL VARCHAR2(10)
BEGIN
  CRS:=DBMS_HS_PASSTHROUGH.OPEN_CURSOR@gtwlink;
  DBMS_HS_PASSTHROUGH.PARSE@gtwlink(CRS,'SELECT NAME FROM PT_TABLE');
BEGIN
  RET:=0;
  WHILE (TRUE)
  LOOP
    RET:=DBMS_HS_PASSTHROUGH.FETCH_ROW@gtwlink(CRS,FALSE);
    DBMS_HS_PASSTHROUGH.GET_VALUE@gtwlink(CRS,1,VAL);
    INSERT INTO PT_TABLE_LOCAL VALUES(VAL);
  END LOOP;
  EXCEPTION
    WHEN NO_DATA_FOUND THEN
      BEGIN
        DBMS_OUTPUT.PUT_LINE('END OF FETCH');
        DBMS_HS_PASSTHROUGH.CLOSE_CURSOR@gtwlink(CRS);
      END;
    END;  
END;
/