111 DBMS_OUTPUT

DBMS_OUTPUTパッケージによって、ストアド・プロシージャ、パッケージおよびトリガーからメッセージを送信できます。このパッケージは、PL/SQLデバッグ情報の表示に特に便利です。

この章のトピックは、次のとおりです:

111.1 DBMS_OUTPUTの概要

通常、このパッケージは、デバッグに使用されるか、あるいはメッセージとレポート(プロシージャにSQLコマンドDESCRIBEを適用するなどして生成)をSQL*DBAまたはSQL*Plusに表示するために使用されます。

このパッケージに含まれているPUTプロシージャおよびPUT_LINEプロシージャによって、別のトリガー、プロシージャまたはパッケージで読み込めるバッファに情報を設定できます。別のPL/SQLプロシージャまたは無名ブロックでは、GET_LINEプロシージャおよびGET_LINESプロシージャをコールして、バッファに入れた情報を表示できます。

パッケージを無効にすると、サブプログラムに対するすべてのコールが無視されます。これによって、クライアントが情報を処理できる場合のみにサブプログラムが使用可能になるように、アプリケーションを設計できます。

111.2 DBMS_OUTPUTのセキュリティ・モデル

dbmsotpt.sqlスクリプトは、ユーザーSYSとして実行する必要があります。これによって、パブリック・シノニムDBMS_OUTPUTが作成され、このパッケージに対するEXECUTE許可がpublicに付与されます。

111.3 DBMS_OUTPUTの使用上の注意

DBMS_OUTPUTには、次の使用上の注意が適用されます。

  • GET_LINEをコールしない場合、またはSQL*Plusのスクリーンにメッセージを表示しない場合、バッファに入れたメッセージは無視されます。

  • SQL*Plusは、SQL文または無名PL/SQLコールを発行した後にGET_LINESをコールします。

  • SQL*PlusにSET SERVEROUTPUT ONを入力すると、次のコマンドが実行されます。

    DBMS_OUTPUT.ENABLE (buffer_size => NULL);
    

    この場合、出力に制限はありません。

  • 通常は、アプリケーション・コードでDISABLEプロシージャ またはENABLEプロシージャを起動しないでください。SQL*Plusなどの外部ツールによって出力を表示するかどうかを制御できなくなる可能性があるためです。

注意:

DBMS_OUTPUTを使用して送信するメッセージは、送信サブプログラムまたはトリガーが完了するまでは実際に送信されません。プロシージャの実行中に出力をフラッシュするメカニズムはありません。

111.4 DBMS_OUTPUTの例外

DBMS_OUTPUTサブプログラムは、アプリケーション・エラーORA-20000を呼び出し、エラーを戻します。

この出力プロシージャでは、次のエラーが戻される場合があります。

表111-1 DBMS_OUTPUTのエラー

エラー 説明

ORU-10027:

バッファのオーバーフロー。

ORU-10028:

行の長さのオーバーフロー。

111.5 DBMS_OUTPUTのルールおよび制限

DBMS_OUTPUT行の制限およびバッファ・サイズは、次のとおりです。

  • 最大行サイズは32767バイトです。

  • デフォルトのバッファ・サイズは20000バイトです。最小サイズは2000バイトで、最大サイズは無制限です。

111.6 DBMS_OUTPUTの例

このトピックには、DBMS_OUTPUTの3つの使用例が含まれます。

例1: トリガーを使用した出力

トリガーを使用して、デバッグ処理の結果を出力できます。たとえば、次のコマンドを実行するトリガーをコード化できます。

DBMS_OUTPUT.PUT_LINE('I got here:'||:new.col||' is the new value'); 

DBMS_OUTPUTパッケージを使用可能にした場合、このPUT_LINEによって生成されたテキストはバッファに入れられ、トリガー文(トリガーを起動させるINSERTDELETEまたはUPDATEが想定できます)の実行後に、情報行を取り出すことができます。次に例を示します。

BEGIN 
   DBMS_OUTPUT.GET_LINE(:buffer, :status); 
END; 

これによって、スクリーンにバッファを表示できます(オプション)。statusが0(ゼロ)以外で戻るまで、GET_LINEへのコールを繰り返します。パフォーマンス向上のためには、行の配列を戻すことができるGET_LINESプロシージャへのコールを使用してください。

例2: ストアド・プロシージャとトリガーのデバッグ

DBMS_OUTPUTパッケージは、一般的に、ストアド・プロシージャおよびトリガーをデバッグするために使用されます。また、「例3: オブジェクトに関する情報の取得」で示すように、このパッケージを使用すると、オブジェクトの情報を取り出し、その出力をフォーマットできます。

このファンクションは、従業員表を問い合せて、指定部門の給与合計を戻します。このファンクションには、次のようにPUT_LINEプロシージャへのコールがいくつか含まれます。

CREATE FUNCTION dept_salary (dnum NUMBER) RETURN NUMBER IS
   CURSOR emp_cursor IS
      SELECT sal, comm FROM emp WHERE deptno = dnum;
   total_wages    NUMBER(11, 2) := 0;
   counter        NUMBER(10) := 1;
BEGIN

   FOR emp_record IN emp_cursor LOOP
      emp_record.comm := NVL(emp_record.comm, 0);
      total_wages := total_wages + emp_record.sal
         + emp_record.comm;
      DBMS_OUTPUT.PUT_LINE('Loop number = ' || counter || 
         '; Wages = '|| TO_CHAR(total_wages));  /* Debug line */
      counter := counter + 1; /* Increment debug counter */
   END LOOP;
   /* Debug line */
   DBMS_OUTPUT.PUT_LINE('Total wages = ' ||
     TO_CHAR(total_wages)); 
   RETURN total_wages;

END dept_salary;

EMP表には、次の行が含まれているとします。

EMPNO          SAL     COMM     DEPT
-----        ------- -------- -------
1002           1500      500      20
1203           1000               30
1289           1000               10
1347           1000      250      20

ユーザーがSQL*Plusの次の文を実行したとします。

SET SERVEROUTPUT ON
VARIABLE salary NUMBER;
EXECUTE :salary := dept_salary(20);

出力ペインには、次の情報が表示されます。

Loop number = 1; Wages = 2000
Loop number = 2; Wages = 3250
Total wages = 3250

PL/SQL procedure successfully executed.

例3: オブジェクトに関する情報の取得

この例では、ユーザーはすでにEXPLAIN PLANコマンドを使用して、ある文の実行計画に関する情報を取り出し、その情報をPLAN_TABLEに格納してあります。また、ユーザーはこの文に文IDを割り当ててあります。EXPLAIN_OUTプロシージャの例では、表から情報を取り出し、出力をネスト形式でフォーマットして、SQL文を処理するステップの順序を厳密に記述しています。

 /****************************************************************/
/* Create EXPLAIN_OUT procedure. User must pass STATEMENT_ID to */
/* to procedure, to uniquely identify statement.                */
/****************************************************************/
CREATE OR REPLACE PROCEDURE explain_out 
   (statement_id IN VARCHAR2) AS 

   -- Retrieve information from PLAN_TABLE into cursor EXPLAIN_ROWS.

   CURSOR explain_rows IS 
      SELECT level, id, position, operation, options,
         object_name 
      FROM plan_table 
      WHERE statement_id = explain_out.statement_id 
      CONNECT BY PRIOR id = parent_id 
         AND statement_id = explain_out.statement_id 
      START WITH id = 0
       ORDER BY id; 
 
BEGIN 

   -- Loop through information retrieved from PLAN_TABLE:

   FOR line IN explain_rows LOOP 

      -- At start of output, include heading with estimated cost.

      IF line.id = 0 THEN 
         DBMS_OUTPUT.PUT_LINE ('Plan for statement '
            || statement_id
            || ', estimated cost = ' || line.position); 
      END IF; 

      -- Output formatted information. LEVEL determines indention level.

      DBMS_OUTPUT.PUT_LINE (lpad(' ',2*(line.level-1)) ||
         line.operation || ' ' || line.options || ' ' || 
         line.object_name); 
   END LOOP; 

END; 

参照:

UTL_FILE

111.7 DBMS_OUTPUTのデータ構造

DBMS_OUTPUTパッケージは、GET_LINESプロシージャで使用するために、2つのコレクション・タイプを宣言します。

表タイプ

CHARARR表タイプ

111.7.1 CHARARR表タイプ

このパッケージ・タイプは、PUTプロシージャおよびPUT_LINEプロシージャを介して送信されたテキストを取得するために、GET_LINESプロシージャで使用されます。

構文

TYPE CHARARR IS TABLE OF VARCHAR2(32767) INDEX BY BINARY_INTEGER;

111.7.2 DBMS_OUTPUT DBMSOUTPUT_LINESARRAYオブジェクト・タイプ

パッケージの外部で定義されたこのタイプは、PUTプロシージャおよびPUT_LINEプロシージャを介して送信されたテキストを取得するために、GET_LINESプロシージャで使用されます。

構文

TYPE DBMSOUTPUT_LINESARRAY IS
     VARRAY(2147483647) OF VARCHAR2(32767);

111.8 DBMS_OUTPUTサブプログラムの要約

この表は、DBMS_OUTPUTサブプログラムを示し、簡単に説明しています。

表111-2 DBMS_OUTPUTパッケージのサブプログラム

サブプログラム 説明

DISABLEプロシージャ

メッセージの出力を無効にします。

ENABLEプロシージャ

メッセージの出力を有効にします。

GET_LINEプロシージャ

バッファから1行取り出します。

GET_LINESプロシージャ

バッファから行の配列を1つ取り出します。

NEW_LINEプロシージャ

PUTを使用して作成した行を終了します。

PUTプロシージャ

行の一部をバッファに設定します。

PUT_LINEプロシージャ

行をバッファに設定します。

注意:

NUMBERデータ・タイプを使用するPUTプロシージャは使用されなくなります。現在はサポートされていますが、このリリースに含まれているのは下位互換性を保つという理由にすぎません。

111.8.1 DISABLEプロシージャ

このプロシージャは、PUTPUT_LINENEW_LINEGET_LINEおよびGET_LINESへのコールを使用禁止にして、残っている情報のバッファをパージします。

ENABLEプロシージャと同様に、SQL*PlusのSERVEROUTPUTオプションを使用する場合は、このプロシージャをコールする必要はありません。

構文

DBMS_OUTPUT.DISABLE;

プラグマ

pragma restrict_references(disable,WNDS,RNDS);

111.8.2 ENABLEプロシージャ

このプロシージャは、PUTPUT_LINENEW_LINEGET_LINEおよびGET_LINESへのコールを使用可能にします。

DBMS_OUTPUTパッケージがアクティブ化されていない場合、これらのプロシージャへのコールは無視されます。

構文

DBMS_OUTPUT.ENABLE (
   buffer_size IN INTEGER DEFAULT 20000);

プラグマ

pragma restrict_references(enable,WNDS,RNDS);

パラメータ

表111-3 ENABLEプロシージャのパラメータ

パラメータ 説明

buffer_size

バッファに入れられる情報量の上限(バイト)。buffer_sizeNULLに設定すると、制限なしと指定されます。

使用上の注意

  • SQL*PlusのSET SERVEROUTPUTオプションを使用する場合は、このプロシージャをコールする必要はありません。

  • ENABLEへのコールが複数の場合、buffer_sizeは最後に指定した値になります。buffer_size(NOT NULL)を指定する場合、最大サイズは1,000,000で、最小サイズは2,000です。

  • 通常は、NULLを選択します。無制限のバッファをサポートしていない、初期のバージョンのデータベースとの下位互換性を保つために、デフォルトは20,000になっています。

111.8.3 GET_LINEプロシージャ

このプロシージャは、バッファに入れられた単一行の情報を取り出します。

構文

DBMS_OUTPUT.GET_LINE (
   line    OUT VARCHAR2,
   status  OUT INTEGER);

パラメータ

表111-4 GET_LINEプロシージャのパラメータ

パラメータ 説明

line

末尾の改行文字を除くバッファに入れられた単一行の情報が、戻されます。「ORA-06502: PL/SQL: 数値または値のエラー: 文字列バッファが小さすぎます」のリスクを回避するために、このパラメータをVARCHAR2(32767)として宣言する必要があります。

status

コールが正常に完了すると、ステータス0(ゼロ)が戻ります。バッファにこれ以上行がない場合は、ステータス1が戻ります。

使用上の注意

  • 単一行または行の配列をバッファから取り出すことができます。バッファに入れられた単一行の情報を取り出すには、GET_LINEプロシージャをコールします。サーバーへのコール数を減らすには、GET_LINESプロシージャをコールして、バッファから行の配列を取り出します。

  • SQL*Plusを使用している場合は、特別のSET SERVEROUTPUT ONコマンドを使用して、この情報を自動的に表示できます。

  • GET_LINEまたはGET_LINESをコールしてから、次にPUTPUT_LINEまたはNEW_LINEをコールする前に取り出されなかった行は、次のメッセージとの混同を避けるために廃棄されます。

111.8.4 GET_LINESプロシージャ

このプロシージャは、バッファから行の配列を取り出します。

構文

DBMS_OUTPUT.GET_LINES (
   lines       OUT     CHARARR,
   numlines    IN OUT  INTEGER);

DBMS_OUTPUT.GET_LINES (
   lines       OUT     DBMSOUTPUT_LINESARRAY,
   numlines    IN OUT INTEGER);

パラメータ

表111-5 GET_LINESプロシージャのパラメータ

パラメータ 説明

lines

バッファに入れられた情報の行の配列を戻します。配列内の各行の最大長は32767バイトです。PL/SQL無名ブロックからプロシージャを実行する場合、3GLホスト・プログラムでVARRAYオーバーロード・バージョンを使用することをお薦めします。

numlines

バッファから取り出す行数。

プロシージャは、指定の行数を取り出した後、実際に取り出した行数を戻します。この数が要求した行数より少ない場合は、バッファにそれ以上行がない場合です。

使用上の注意

  • 単一行または行の配列をバッファから取り出すことができます。バッファに入れられた単一行の情報を取り出すには、GET_LINEプロシージャをコールします。サーバーへのコール数を減らすには、GET_LINESプロシージャをコールして、バッファから行の配列を取り出します。

  • SQL*Plusを使用している場合は、特別のSET SERVEROUTPUT ONコマンドを使用して、この情報を自動的に表示できます。

  • GET_LINEまたはGET_LINESをコールしてから、次にPUTPUT_LINEまたはNEW_LINEをコールする前に取り出されなかった行は、次のメッセージとの混同を避けるために廃棄されます。

111.8.5 NEW_LINEプロシージャ

このプロシージャは、行端マーカーを設定します。

GET_LINEプロシージャおよびGET_LINESプロシージャは、改行で区切られた行を戻します。PUT_LINEプロシージャまたはNEW_LINEプロシージャへのすべてのコールによって、GET_LINE(S)で戻される行が生成されます。

構文

DBMS_OUTPUT.NEW_LINE;

111.8.6 PUTプロシージャ

このプロシージャは、行の一部をバッファに設定します。

注意:

NUMBERデータ・タイプを使用するPUTプロシージャは使用されなくなります。現在はサポートされますが、このリリースに含まれているのは下位互換性を保つという理由にすぎません。

構文

DBMS_OUTPUT.PUT (
    item IN VARCHAR2);

パラメータ

表111-6 PUTプロシージャのパラメータ

パラメータ 説明

item

バッファに設定する項目。

例外

表111-7 PUTプロシージャの例外

エラー 説明

ORA-20000、ORU-10027:

バッファのオーバーフロー。バッファは<buf_limit>バイトに制限されています。

ORA-20000、ORU-10028:

行の長さのオーバーフロー。各行につき32767バイトに制限されています。

使用上の注意

  • PUTを複数回コールすることによって個別に情報行を作成するか、PUT_LINEをコールして情報行全体をバッファに設定することができます。

  • PUT_LINEをコールすると、指定した項目には行端マーカーが自動的に付きます。PUTをコールして行を作成する場合は、NEW_LINEをコールして行端マーカーを追加する必要があります。GET_LINEおよびGET_LINESは、改行文字で終了していない行は戻しません。

  • 行が行制限を超えた場合は、エラー・メッセージを受信します。

  • PUTまたはPUT_LINEで作成した出力はバッファに入れられます。この出力は、それをバッファに入れたPL/SQLプログラム・ユニットがコール元に戻るまで取り出せません。

    たとえば、SQL*Plusは、PL/SQLプログラムが完了するまでDBMS_OUTPUTメッセージを表示しません。PL/SQLプログラム内でDBMS_OUTPUTバッファをフラッシュするメカニズムはありません。

    SQL> SET SERVEROUTPUT ON
    SQL> BEGIN
      2  DBMS_OUTPUT.PUT_LINE ('hello');
      3  DBMS_LOCK.SLEEP (10);
      4  END;

111.8.7 PUT_LINEプロシージャ

このプロシージャは、行をバッファに設定します。

注意:

NUMBERデータ・タイプを使用するPUT_LINEプロシージャは使用されなくなります。現在はサポートされますが、このリリースに含まれているのは下位互換性を保つという理由にすぎません。

構文

DBMS_OUTPUT.PUT_LINE (
   item IN VARCHAR2);

パラメータ

表111-8 PUT_LINEプロシージャのパラメータ

パラメータ 説明

item

バッファに設定する項目。

例外

表111-9 PUT_LINEプロシージャの例外

エラー 説明

ORA-20000、ORU-10027:

バッファのオーバーフロー。バッファは<buf_limit>バイトに制限されています。

ORA-20000、ORU-10028:

行の長さのオーバーフロー。各行につき32767バイトに制限されています。

使用上の注意

  • PUTを複数回コールすることによって個別に情報行を作成するか、PUT_LINEをコールして情報行全体をバッファに設定することができます。

  • PUT_LINEをコールすると、指定した項目には行端マーカーが自動的に付きます。PUTをコールして行を作成する場合は、NEW_LINEをコールして行端マーカーを追加する必要があります。GET_LINEおよびGET_LINESは、改行文字で終了していない行は戻しません。

  • 行が行制限を超えた場合は、エラー・メッセージを受信します。

  • PUTまたはPUT_LINEで作成した出力はバッファに入れられます。この出力は、それをバッファに入れたPL/SQLプログラム・ユニットがコール元に戻るまで取り出せません。

    たとえば、SQL*Plusは、PL/SQLプログラムが完了するまでDBMS_OUTPUTメッセージを表示しません。PL/SQLプログラム内でDBMS_OUTPUTバッファをフラッシュするメカニズムはありません。次に例を示します。

    SQL> SET SERVEROUTPUT ON
    SQL> BEGIN
       2 DBMS_OUTPUT.PUT_LINE ('hello');
       3 DBMS_LOCK.SLEEP (10);
       4 END;