122 DBMS_OUTPUT
DBMS_OUTPUTパッケージによって、ストアド・プロシージャ、パッケージおよびトリガーからメッセージを送信できます。このパッケージは、PL/SQLデバッグ情報の表示に特に便利です。
この章のトピックは、次のとおりです:
122.1 DBMS_OUTPUTの概要
通常、このパッケージは、デバッグに使用されるか、あるいはメッセージとレポート(プロシージャにSQLコマンドDESCRIBEを適用するなどして生成)をSQL*DBAまたはSQL*Plusに表示するために使用されます。
このパッケージに含まれているPUTプロシージャおよびPUT_LINEプロシージャによって、別のトリガー、プロシージャまたはパッケージで読み込めるバッファに情報を設定できます。別のPL/SQLプロシージャまたは無名ブロックでは、GET_LINEプロシージャおよびGET_LINESプロシージャをコールして、バッファに入れた情報を表示できます。
パッケージを無効にすると、サブプログラムに対するすべてのコールが無視されます。これによって、クライアントが情報を処理できる場合のみにサブプログラムが使用可能になるように、アプリケーションを設計できます。
122.2 DBMS_OUTPUTのセキュリティ・モデル
dbmsotpt.sqlスクリプトは、ユーザーSYSとして実行する必要があります。これによって、パブリック・シノニムDBMS_OUTPUTが作成され、このパッケージに対するEXECUTE許可がpublicに付与されます。
122.3 DBMS_OUTPUTの操作上のノート
DBMS_OUTPUTには、次の操作上のノートが適用されます。
-
GET_LINEをコールしない場合、またはSQL*Plusのスクリーンにメッセージを表示しない場合、バッファに入れたメッセージは無視されます。 -
SQL*Plusは、SQL文または無名PL/SQLコールを発行した後に
GET_LINESをコールします。 -
SQL*Plusに
SETSERVEROUTPUTONを入力すると、次のコマンドが実行されます。DBMS_OUTPUT.ENABLE (buffer_size => NULL);
この場合、出力に制限はありません。
-
通常は、アプリケーション・コードでDISABLEプロシージャ またはENABLEプロシージャを起動しないでください。SQL*Plusなどの外部ツールによって出力を表示するかどうかを制御できなくなる可能性があるためです。
ノート:
DBMS_OUTPUTを使用して送信するメッセージは、送信サブプログラムまたはトリガーが完了するまでは実際に送信されません。プロシージャの実行中に出力をフラッシュするメカニズムはありません。
122.4 DBMS_OUTPUTの例外
DBMS_OUTPUTサブプログラムは、アプリケーション・エラーORA-20000を呼び出し、エラーを戻します。
この出力プロシージャでは、次のエラーが戻される場合があります。
表122-1 DBMS_OUTPUTのエラー
| エラー | 説明 |
|---|---|
|
|
バッファのオーバーフロー。 |
|
|
行の長さのオーバーフロー。 |
122.5 DBMS_OUTPUTのルールおよび制限
DBMS_OUTPUT行の制限およびバッファ・サイズは、次のとおりです。
-
最大行サイズは32767バイトです。
-
デフォルトのバッファ・サイズは20000バイトです。最小サイズは2000バイトで、最大サイズは無制限です。
122.6 DBMS_OUTPUTの例
このトピックには、DBMS_OUTPUTの3つの使用例が含まれます。
例1: トリガーを使用した出力
トリガーを使用して、デバッグ処理の結果を出力できます。たとえば、次のコマンドを実行するトリガーをコード化できます。
DBMS_OUTPUT.PUT_LINE('I got here:'||:new.col||' is the new value');
DBMS_OUTPUTパッケージを使用可能にした場合、このPUT_LINEによって生成されたテキストはバッファに入れられ、トリガー文(トリガーを起動させるINSERT、DELETEまたは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; 参照:
122.7 DBMS_OUTPUTのデータ構造
DBMS_OUTPUTパッケージは、GET_LINESプロシージャで使用するために、2つのコレクション・タイプを宣言します。
表タイプ
オブジェクト・タイプ
関連トピック
122.7.1 CHARARR表タイプ
このパッケージ・タイプは、PUTプロシージャおよびPUT_LINEプロシージャを介して送信されたテキストを取得するために、GET_LINESプロシージャで使用されます。
構文
TYPE CHARARR IS TABLE OF VARCHAR2(32767) INDEX BY BINARY_INTEGER;
122.8 DBMS_OUTPUTサブプログラムの要約
この表は、DBMS_OUTPUTサブプログラムを示し、簡単に説明しています。
表122-2 DBMS_OUTPUTパッケージのサブプログラム
| サブプログラム | 説明 |
|---|---|
|
メッセージの出力を無効にします。 |
|
|
メッセージの出力を有効にします。 |
|
|
バッファから1行取り出します。 |
|
|
バッファから行の配列を1つ取り出します。 |
|
|
|
|
|
行の一部をバッファに設定します。 |
|
|
行をバッファに設定します。 |
ノート:
NUMBERデータ・タイプを使用するPUTプロシージャは使用されなくなります。現在はサポートされていますが、このリリースに含まれているのは下位互換性を保つという理由にすぎません。
122.8.1 DISABLEプロシージャ
このプロシージャは、PUT、PUT_LINE、NEW_LINE、GET_LINEおよびGET_LINESへのコールを使用禁止にして、残っている情報のバッファをパージします。
ENABLEプロシージャと同様に、SQL*PlusのSERVEROUTPUTオプションを使用する場合は、このプロシージャをコールする必要はありません。
構文
DBMS_OUTPUT.DISABLE;
プラグマ
pragma restrict_references(disable,WNDS,RNDS);
122.8.2 ENABLEプロシージャ
このプロシージャは、PUT、PUT_LINE、NEW_LINE、GET_LINEおよびGET_LINESへのコールを使用可能にします。
DBMS_OUTPUTパッケージがアクティブ化されていない場合、これらのプロシージャへのコールは無視されます。
構文
DBMS_OUTPUT.ENABLE ( buffer_size IN INTEGER DEFAULT 20000);
プラグマ
pragma restrict_references(enable,WNDS,RNDS);
パラメータ
表122-3 ENABLEプロシージャのパラメータ
| パラメータ | 説明 |
|---|---|
|
|
バッファに入れられる情報量の上限(バイト)。 |
使用上のノート
-
SQL*Plusの
SETSERVEROUTPUTオプションを使用する場合は、このプロシージャをコールする必要はありません。 -
ENABLEへのコールが複数の場合、buffer_sizeは最後に指定した値になります。buffer_size(NOTNULL)を指定する場合、最大サイズは1,000,000で、最小サイズは2,000です。 -
通常は、
NULLを選択します。無制限のバッファをサポートしていない、初期のバージョンのデータベースとの下位互換性を保つために、デフォルトは20,000になっています。
122.8.3 GET_LINEプロシージャ
このプロシージャは、バッファに入れられた単一行の情報を取り出します。
構文
DBMS_OUTPUT.GET_LINE ( line OUT VARCHAR2, status OUT INTEGER);
パラメータ
表122-4 GET_LINEプロシージャのパラメータ
| パラメータ | 説明 |
|---|---|
|
|
末尾の改行文字を除くバッファに入れられた単一行の情報が、戻されます。 |
|
|
コールが正常に完了すると、ステータス0(ゼロ)が戻ります。バッファにこれ以上行がない場合は、ステータス1が戻ります。 |
使用上のノート
-
単一行または行の配列をバッファから取り出すことができます。バッファに入れられた単一行の情報を取り出すには、
GET_LINEプロシージャをコールします。サーバーへのコール数を減らすには、GET_LINESプロシージャをコールして、バッファから行の配列を取り出します。 -
SQL*Plusを使用している場合は、特別の
SETSERVEROUTPUTONコマンドを使用して、この情報を自動的に表示できます。 -
GET_LINEまたはGET_LINESをコールしてから、次にPUT、PUT_LINEまたはNEW_LINEをコールする前に取り出されなかった行は、次のメッセージとの混同を避けるために廃棄されます。
122.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);
パラメータ
表122-5 GET_LINESプロシージャのパラメータ
| パラメータ | 説明 |
|---|---|
|
|
バッファに入れられた情報の行の配列を戻します。配列内の各行の最大長は32767バイトです。PL/SQL無名ブロックからプロシージャを実行する場合、3GLホスト・プログラムで |
|
|
バッファから取り出す行数。 プロシージャは、指定の行数を取り出した後、実際に取り出した行数を戻します。この数が要求した行数より少ない場合は、バッファにそれ以上行がない場合です。 |
使用上のノート
-
単一行または行の配列をバッファから取り出すことができます。バッファに入れられた単一行の情報を取り出すには、
GET_LINEプロシージャをコールします。サーバーへのコール数を減らすには、GET_LINESプロシージャをコールして、バッファから行の配列を取り出します。 -
SQL*Plusを使用している場合は、特別の
SETSERVEROUTPUTONコマンドを使用して、この情報を自動的に表示できます。 -
GET_LINEまたはGET_LINESをコールしてから、次にPUT、PUT_LINEまたはNEW_LINEをコールする前に取り出されなかった行は、次のメッセージとの混同を避けるために廃棄されます。
122.8.5 NEW_LINEプロシージャ
このプロシージャは、行端マーカーを設定します。
GET_LINEプロシージャおよびGET_LINESプロシージャは、改行で区切られた行を戻します。PUT_LINEプロシージャまたはNEW_LINEプロシージャへのすべてのコールによって、GET_LINE(S)で戻される行が生成されます。
構文
DBMS_OUTPUT.NEW_LINE;
122.8.6 PUTプロシージャ
このプロシージャは、行の一部をバッファに設定します。
ノート:
NUMBERデータ・タイプを使用するPUTプロシージャは使用されなくなります。現在はサポートされますが、このリリースに含まれているのは下位互換性を保つという理由にすぎません。
構文
DBMS_OUTPUT.PUT (
item IN VARCHAR2);パラメータ
表122-6 PUTプロシージャのパラメータ
| パラメータ | 説明 |
|---|---|
|
|
バッファに設定する項目。 |
例外
表122-7 PUTプロシージャの例外
| エラー | 説明 |
|---|---|
|
|
バッファのオーバーフロー。バッファは< |
|
|
行の長さのオーバーフロー。各行につき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;
122.8.7 PUT_LINEプロシージャ
このプロシージャは、行をバッファに設定します。
ノート:
NUMBERデータ・タイプを使用するPUT_LINEプロシージャは使用されなくなります。現在はサポートされますが、このリリースに含まれているのは下位互換性を保つという理由にすぎません。
構文
DBMS_OUTPUT.PUT_LINE ( item IN VARCHAR2);
パラメータ
表122-8 PUT_LINEプロシージャのパラメータ
| パラメータ | 説明 |
|---|---|
|
|
バッファに設定する項目。 |
例外
表122-9 PUT_LINEプロシージャの例外
| エラー | 説明 |
|---|---|
|
|
バッファのオーバーフロー。バッファは< |
|
|
行の長さのオーバーフロー。各行につき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;