説明 クラスターエンドポイントでDBMS_PIPEパッケージを使用しないことを推奨します。 これは、長時間のトランザクションを引き起こす可能性があります。
次の表に、
DBMS_PIPEパッケージで使用できる関数とストアドプロシージャを示します。
表1. DBMS_PIPEパッケージの関数とストアドプロシージャを | 関数またはストアドプロシージャ | 戻り値の型 | 説明 |
| CREATE_PIPE(pipename [, maxpipesize ] [, private ]) | INTEGER | パブリックまたはプライベートパイプを明示的に作成します。 |
| NEXT_ITEM_TYPE | INTEGER | 受信したメッセージの次の项目のデータ型を返します。 |
| PACK_MESSAGE (アイテム) | N/A | 現在のセッションのローカルメッセージバッファにデータ項目を配置します。 |
| PURGE(pipename) | N/A | 指定された暗黙的に作成されたパイプから未受信メッセージを削除します。 |
| RECEIVE_MESSAGE(pipename [, timeout ]) | INTEGER | 指定されたパイプからメッセージを取得します。 |
| REMOVE_PIPE(pipename) | INTEGER | 明示的に作成されたパイプを削除します。 |
| RESET_BUFFER | N/A | ローカルメッセージバッファーをリセットします。 |
| SEND_MESSAGE(pipename [, timeout ] [, maxpipesize ]) | INTEGER | 現在のセッションのローカルメッセージバッファから指定されたパイプにメッセージを送信します。 |
| UNIQUE_SESSION_NAME | VARCHAR2 | 現在のセッションの一意の名前を取得します。 |
| UNPACK_MESSAGE (アイテムアウト) | N/A | メッセージのデータ項目をローカルメッセージバッファからプログラム変数にコピーします。 |
CREATE_PIPE
CREATE_PIPE関数は、指定された名前のパブリックパイプまたはプライベートパイプを明示的に作成するために使用されます。 構文:
ステータスINTEGER CREATE_PIPE(pipename VARCHAR2)
[, maxpipesize INTEGER ] [, private BOOLEAN ])
パラメータ| パラメーター | 説明 |
| pipename | パイプの名前。 |
| maxpipesize | パイプの最大容量。 単位:バイト デフォルト値は 8192 です。 |
| private | パブリックパイプを作成するには、このパラメーターをFALSEに設定します。 プライベートパイプを作成するには、このパラメーターをTRUEに設定します。 デフォルト値は TRUE です。 |
| status | 操作によって返されたステータスコード。 0 は作成が成功したことを示します。 |
例- 次の例では、messagesという名前のプライベートパイプを作成します。
v_status INTEGER;
開始
v_status := DBMS_PIPE.CREATE_PIPE('messages');
DBMS_OUTPUT.PUT_LINE('CREATE_PIPEステータス: '| | v_status);
END;
次の出力が表示されます。CREATE_PIPE status: 0
- 次の例では、mailboxという名前のパブリックパイプを作成します。
v_status INTEGER;
開始
v_status := DBMS_PIPE.CREATE_PIPE('mailbox',8192,FALSE);
DBMS_OUTPUT.PUT_LINE('CREATE_PIPEステータス: '| | v_status);
END;
次の出力が表示されます。CREATE_PIPE status: 0
NEXT_ITEM_TYPE
NEXT_ITEM_TYPE関数は整数コードを返します。 このコードは、現在のセッションのローカルメッセージバッファに取り出されたメッセージ内の次のデータ項目のデータ型を識別するために使用される。
UNPACK_MESSAGEストアドプロシージャによってローカルメッセージバッファから項目が削除された場合、
NEXT_ITEM_TYPE関数は次に使用可能な項目のデータ型コードを返します。 メッセージに項目が存在しない場合は、データ型コード0が返されます。 構文:
typecode INTEGER NEXT_ITEM_TYPE
パラメーター表2. NEXT_ITEM_TYPE関数によって返されるデータ型コード| 返されたコード | 説明 |
| 0 | これ以上のデータ項目はありません。 |
| 9 | NUMBER |
| 11 | VARCHAR2 |
| 13 | 日付 |
| 23 | RAW |
説明 表に示すデータ型コードは、Oracleデータベースと互換性がありません。 Oracleは、データ型に異なる番号付けシーケンスを割り当てます。
例次の例は、NUMBER 項目、VARCHAR2 項目、DATE 項目、および RAW 項目をパックしたパイプを示しています。
DECLARE
v_number NUMBER := 123;
v_varchar VARCHAR2(20) := 'Character data';
v_date DATE := SYSDATE;
v_raw RAW(4) := '21222324';
v_status INTEGER;
開始
DBMS_PIPE.PACK_MESSAGE(v_number);
DBMS_PIPE.PACK_MESSAGE(v_varchar);
DBMS_PIPE.PACK_MESSAGE(v_date);
DBMS_PIPE.PACK_MESSAGE(v_raw);
v_status := DBMS_PIPE.SEND_MESSAGE('datatypes');
DBMS_OUTPUT.PUT_LINE('SEND_MESSAGEステータス: '| | v_status);
例外
WHEN OTHERS THEN
DBMS_OUTPUT.PUT_LINE('SQLERRM: ' || SQLERRM);
DBMS_OUTPUT.PUT_LINE('SQLCODE: '| | SQLCODE);
END;
次の出力が表示されます。
SEND_MESSAGE status: 0
次の例は、NEXT_ITEM_type関数によって返される前の例の各データ項目の型コードを示しています。 DECLARE
v_number NUMBER;
v_varchar VARCHAR2(20);
v_date DATE;
v_timestamp TIMESTAMP;
v_raw RAW(4);
v_status INTEGER;
開始
v_status := DBMS_PIPE.RECEIVE_MESSAGE('datatypes');
DBMS_OUTPUT.PUT_LINE('RECEIVE_MESSAGE status: ' || v_status);
DBMS_OUTPUT.PUT_LINE('----------------------------------');
v_status := DBMS_PIPE.NEXT_ITEM_TYPE;
DBMS_OUTPUT.PUT_LINE('NEXT_ITEM_TYPE: ' || v_status);
DBMS_PIPE.UNPACK_MESSAGE(v_number);
DBMS_OUTPUT.PUT_LINE('NUMBER Item : ' || v_number);
DBMS_OUTPUT.PUT_LINE('----------------------------------');
v_status := DBMS_PIPE.NEXT_ITEM_TYPE;
DBMS_OUTPUT.PUT_LINE('NEXT_ITEM_TYPE: ' || v_status);
DBMS_PIPE.UNPACK_MESSAGE(v_varchar);
DBMS_OUTPUT.PUT_LINE('VARCHAR2 Item : ' || v_varchar);
DBMS_OUTPUT.PUT_LINE('----------------------------------');
v_status := DBMS_PIPE.NEXT_ITEM_TYPE;
DBMS_OUTPUT.PUT_LINE('NEXT_ITEM_TYPE: ' || v_status);
DBMS_PIPE.UNPACK_MESSAGE(v_date);
DBMS_OUTPUT.PUT_LINE('DATE Item : ' || v_date);
DBMS_OUTPUT.PUT_LINE('----------------------------------');
v_status := DBMS_PIPE.NEXT_ITEM_TYPE;
DBMS_OUTPUT.PUT_LINE('NEXT_ITEM_TYPE: ' || v_status);
DBMS_PIPE.UNPACK_MESSAGE(v_raw);
DBMS_OUTPUT.PUT_LINE('RAW Item : ' || v_raw);
DBMS_OUTPUT.PUT_LINE('----------------------------------');
v_status := DBMS_PIPE.NEXT_ITEM_TYPE;
DBMS_OUTPUT.PUT_LINE('NEXT_ITEM_TYPE: ' || v_status);
DBMS_OUTPUT.PUT_LINE('---------------------------------');
例外
WHEN OTHERS THEN
DBMS_OUTPUT.PUT_LINE('SQLERRM: ' || SQLERRM);
DBMS_OUTPUT.PUT_LINE('SQLCODE: '| | SQLCODE);
END;
次の出力が表示されます。RECEIVE_MESSAGEステータス: 0
----------------------------------
NEXT_ITEM_TYPE: 9
番号アイテム: 123
----------------------------------
NEXT_ITEM_TYPE: 11
VARCHAR2アイテム: 文字データ
----------------------------------
NEXT_ITEM_TYPE: 13
日付アイテム: 02-OCT-07 11:11:43
----------------------------------
NEXT_ITEM_TYPE: 23
RAWアイテム: 21222324
----------------------------------
NEXT_ITEM_TYPE: 0
PACK_MESSAGE
PACK_MESSAGE関数は、現在のセッションのローカルメッセージバッファにデータ項目を配置するために使用されます。
SEND_MESSAGE関数を呼び出す前に、
PACK_MESSAGE関数を少なくとも1回呼び出す必要があります。 構文:
PACK_MESSAGE(item { DATE | NUMBER | VARCHAR2 | RAW })
パラメータ| パラメーター | 説明 |
| 項目 | 受け入れ可能なデータ型のパラメーター値を計算します。 計算された値は、セッションのローカルメッセージバッファに追加される。 |
PURGE
PURGEストアドプロシージャは、指定された暗黙的に作成されたパイプから未受信メッセージを削除するために使用されます。 構文:
PURGE(pipename VARCHAR2)
パラメーター 例次の例は、パイプで2つのメッセージを送信します。
v_status INTEGER;
開始
DBMS_PIPE.PACK_MESSAGE('Message #1');
v_status := DBMS_PIPE.SEND_MESSAGE('pipe');
DBMS_OUTPUT.PUT_LINE('SEND_MESSAGE status: ' || v_status);
DBMS_PIPE.PACK_MESSAGE('Message #2');
v_status := DBMS_PIPE.SEND_MESSAGE('pipe');
DBMS_OUTPUT.PUT_LINE('SEND_MESSAGEステータス: '| | v_status);
END;
次の出力が表示されます。
SEND_MESSAGE status: 0
SEND_MESSAGEステータス: 0
次の例では、最初のメッセージを受信して解凍します。
DECLARE
v_item VARCHAR2(80);
v_status INTEGER;
開始
v_status := DBMS_PIPE.RECEIVE_MESSAGE('pipe',1);
DBMS_OUTPUT.PUT_LINE('RECEIVE_MESSAGE status: ' || v_status);
DBMS_PIPE.UNPACK_MESSAGE(v_item);
DBMS_OUTPUT.PUT_LINE('Item: '| | v_item);
END;
次の出力が表示されます。RECEIVE_MESSAGEステータス: 0
アイテム: メッセージ #1
次の例は、パイプをパージする。EXEC DBMS_PIPE.PURGE('pipe');
次の例は、次のメッセージを検索する試みを示す。 RECEIVE_MESSAGE呼び出しは、ステータスコードを返します。 DECLARE
v_item VARCHAR2(80);
v_status INTEGER;
開始
v_status := DBMS_PIPE.RECEIVE_MESSAGE('pipe',1);
DBMS_OUTPUT.PUT_LINE('RECEIVE_MESSAGEステータス: '| | v_status);
END;
次の出力に表示されるように、ステータスコード1が返されます。これは、使用可能なメッセージがないためにタイムアウトが発生したことを示します。 RECEIVE_MESSAGEステータス: 1
RECEIVE_MESSAGE
RECEIVE_MESSAGE関数は、指定されたパイプからメッセージを取得するために使用されます。 構文:
ステータスINTEGER RECEIVE_MESSAGE(pipename VARCHAR2)
[, timeout INTEGER ])
パラメータ| パラメーター | 説明 |
| pipename | パイプの名前。 |
| timeout | ノードを実行するために使用可能なリソースを待つのに費やした時間。 単位は秒です。 デフォルト値は 86400000 (1000 日) です。 |
表3. RECEIVE_MESSAGE関数によって返される可能なステータスコード| ステータスコード | 説明 |
| 0 | メッセージが正常に受信されました。 |
| 1 | 操作がタイムアウトします。 |
| 2 | パイプ内のメッセージがバッファに対して大きすぎます。 |
| 3 | 操作は中断されます。 |
| ORA-23322 | パイプ内のメッセージにアクセスする権限がありません。 |
REMOVE_PIPE
REMOVE_PIPE関数は、明示的に作成されたプライベートまたはパブリックパイプを削除するために使用されます。 構文:
status INTEGER REMOVE_PIPE(pipename VARCHAR2)
パラメータ| パラメーター | 説明 |
| pipename | パイプの名前。 |
| status | 操作によって返されたステータスコード。 指定されたパイプが存在しなくてもステータスコード0が返されます。 |
例次の例は、パイプで2つのメッセージを送信します。
v_status INTEGER;
開始
v_status := DBMS_PIPE.CREATE_PIPE('pipe');
DBMS_OUTPUT.PUT_LINE('CREATE_PIPE status : ' || v_status);
DBMS_PIPE.PACK_MESSAGE('Message #1');
v_status := DBMS_PIPE.SEND_MESSAGE('pipe');
DBMS_OUTPUT.PUT_LINE('SEND_MESSAGE status: ' || v_status);
DBMS_PIPE.PACK_MESSAGE('Message #2');
v_status := DBMS_PIPE.SEND_MESSAGE('pipe');
DBMS_OUTPUT.PUT_LINE('SEND_MESSAGEステータス: '| | v_status);
END;
次の出力が表示されます。
CREATE_PIPEステータス: 0
SEND_MESSAGEステータス: 0
SEND_MESSAGEステータス: 0
次の例では、最初のメッセージを受信して解凍します。
DECLARE
v_item VARCHAR2(80);
v_status INTEGER;
開始
v_status := DBMS_PIPE.RECEIVE_MESSAGE('pipe',1);
DBMS_OUTPUT.PUT_LINE('RECEIVE_MESSAGE status: ' || v_status);
DBMS_PIPE.UNPACK_MESSAGE(v_item);
DBMS_OUTPUT.PUT_LINE('Item: '| | v_item);
END;
次の出力が表示されます。RECEIVE_MESSAGEステータス: 0
アイテム: メッセージ #1
次の例では、パイプを削除します。SELECT DBMS_PIPE.REMOVE_PIPE('pipe') FROM DUAL;
次の出力が表示されます。remove_pipe
-------------
0
(1行)
次のコード例は、次のメッセージを取得する試みを示しています。 RECEIVE_MESSAGE呼び出しは、パイプが削除されたためにタイムアウトが発生したことを示すステータスコード1を返します。 DECLARE
v_item VARCHAR2(80);
v_status INTEGER;
開始
v_status := DBMS_PIPE.RECEIVE_MESSAGE('pipe',1);
DBMS_OUTPUT.PUT_LINE('RECEIVE_MESSAGEステータス: '| | v_status);
END;
次の出力が表示されます。RECEIVE_MESSAGE status: 1
RESET_BUFFER
RESET_BUFFERストアドプロシージャは、ローカルメッセージバッファへのポインタをバッファの先頭にリセットするために使用される。 これにより、後続の
PACK_MESSAGE呼び出しは、
RESET_BUFFER呼び出しの前にメッセージバッファに存在していたデータ項目を上書きできます。 構文:
RESET_BUFFER
例次の例では、
Johnへのメッセージをローカルメッセージバッファに書き込みます。
RESET_BUFFERコールは、このメッセージを
ボブへのメッセージに置き換える。
DECLARE
v_status INTEGER;
開始
DBMS_PIPE.PACK_MESSAGE('Hi, John');
DBMS_PIPE.PACK_MESSAGE (「今日の3時に会議に出席できますか? 」);
DBMS_PIPE.PACK_MESSAGE (「そうでなければ、明日は8:30にあなたと大丈夫ですか? 」);
DBMS_PIPE.RESET_BUFFER;
DBMS_PIPE.PACK_MESSAGE('Hi, Bob');
DBMS_PIPE.PACK_MESSAGE (「明日9時30分に会議に出席できますか? 」);
v_status := DBMS_PIPE.SEND_MESSAGE('pipe');
DBMS_OUTPUT.PUT_LINE('SEND_MESSAGEステータス: '| | v_status);
END;
次の出力が表示されます。
SEND_MESSAGE status: 0
受信したメッセージに
Bobへのメッセージが表示されます。
DECLARE
v_item VARCHAR2(80);
v_status INTEGER;
開始
v_status := DBMS_PIPE.RECEIVE_MESSAGE('pipe',1);
DBMS_OUTPUT.PUT_LINE('RECEIVE_MESSAGE status: ' || v_status);
DBMS_PIPE.UNPACK_MESSAGE(v_item);
DBMS_OUTPUT.PUT_LINE('Item: ' || v_item);
DBMS_PIPE.UNPACK_MESSAGE(v_item);
DBMS_OUTPUT.PUT_LINE('Item: '| | v_item);
END;
次の出力が表示されます。
RECEIVE_MESSAGEステータス: 0
アイテム: こんにちは、ボブ
アイテム: 明日9時30分に会議に出席できますか?
SEND_MESSAGE
SEND_MESSAGE関数は、ローカルメッセージバッファから指定されたパイプにメッセージを送信するために使用されます。 構文:
ステータスSEND_MESSAGE(pipename VARCHAR2 [, timeout INTEGER])
[, maxpipesize INTEGER ])
パラメータ| パラメーター | 説明 |
| pipename | パイプの名前。 |
| timeout | タイムアウト期間。 単位は秒です。 デフォルト値は 86400000 (1000 日) です。 |
| maxpipesize | パイプの最大容量。 単位:バイト デフォルト値は 8192 です。 |
表4. SEND_MESSAGE関数によって返される可能なステータスコード| ステータスコード | 説明 |
| 0 | メッセージが正常に送信されました。 |
| 1 | 操作がタイムアウトします。 |
| 3 | 操作は中断されます。 |
| ORA-23322 | この操作を実行する権限がありません。
説明 同じ名前のパイプがあり、そのパイプが別のユーザーによって作成されている場合、Oracleは名前の競合を示すエラーコードORA-23322を発行します。 |
UNIQUE_SESSION_NAME
UNIQUE_SESSION_NAME関数は、現在のセッションに固有の名前を返すために使用されます。 構文:
name VARCHAR2 UNIQUE_SESSION_NAME
パラメーターDECLARE
の例
v_session VARCHAR2(30);
開始
v_session := DBMS_PIPE.UNIQUE_SESSION_NAME;
DBMS_OUTPUT.PUT_LINE('Session Name: '| | v_session);
END;
次の出力が表示されます。
セッション名: PG$PIPE$5$2752
UNPACK_MESSAGE
UNPACK_MESSAGEストアドプロシージャは、メッセージのデータ項目をローカルメッセージバッファからプログラム変数にコピーするために使用されます。
UNPACK_MESSAGEストアドプロシージャを使用する前に、
RECEIVE_message関数を使用してメッセージをローカルメッセージバッファに配置する必要があります。 構文:
UNPACK_MESSAGE(item OUT { DATE | NUMBER | VARCHAR2 | RAW })
パラメータ| パラメーター | 説明 |
| 項目 | ローカルメッセージバッファーからデータ項目を受け取る変数。 この変数は、データ項目の型と互換性がある必要があります。 |
Comprehensive example
次の例では、パイプは「メールボックス」として使用されます。 一連のストアドプロシージャを使用して、メールボックスを作成し、メールボックスに複数項目のメッセージ (最大3つの項目) を追加し、メールボックスの全内容を表示します。 これらのストアドプロシージャは、
mailboxという名前のパッケージに囲まれています。
パッケージメールボックスの作成または交換
IS
PROCEDURE create_mailbox;
PROCEDURE add_message (
p_mailbox VARCHAR2,
p_item_1 VARCHAR2,
p_item_2 VARCHAR2 DEFAULT 'END',
p_item_3 VARCHAR2 DEFAULT 'END'
);
PROCEDURE empty_mailbox (
p_mailbox VARCHAR2,
p_waittime INTEGER DEFAULT 10
);
ENDメールボックス;
パッケージ本体メールボックスの作成または交換
IS
PROCEDURE create_mailbox
IS
v_mailbox VARCHAR2(30);
v_status INTEGER;
BEGIN
v_mailbox := DBMS_PIPE.UNIQUE_SESSION_NAME;
v_status := DBMS_PIPE.CREATE_PIPE(v_mailbox,1000,FALSE);
IF v_status = 0 THEN
DBMS_OUTPUT.PUT_LINE('Created mailbox: ' || v_mailbox);
ELSE
DBMS_OUTPUT.PUT_LINE('CREATE_PIPE failed - status: ' ||
v_status);
END IF;
END create_mailbox;
PROCEDURE add_message (
p_mailbox VARCHAR2,
p_item_1 VARCHAR2,
p_item_2 VARCHAR2 DEFAULT 'END',
p_item_3 VARCHAR2 DEFAULT 'END'
)
IS
v_item_cnt INTEGER := 0;
v_status INTEGER;
BEGIN
DBMS_PIPE.PACK_MESSAGE(p_item_1);
v_item_cnt := 1;
IF p_item_2! ='END' THEN
DBMS_PIPE.PACK_MESSAGE(p_item_2);
v_item_cnt := v_item_cnt + 1;
END IF;
IF p_item_3! ='END' THEN
DBMS_PIPE.PACK_MESSAGE(p_item_3);
v_item_cnt := v_item_cnt + 1;
END IF;
v_status := DBMS_PIPE.SEND_MESSAGE(p_mailbox);
IF v_status = 0 THEN
DBMS_OUTPUT.PUT_LINE('Added message with ' || v_item_cnt ||
' item(s) to mailbox ' || p_mailbox);
ELSE
DBMS_OUTPUT.PUT_LINE('SEND_MESSAGE in add_message failed - ' ||
'status: ' || v_status);
END IF;
END add_message;
PROCEDURE empty_mailbox (
p_mailbox VARCHAR2,
p_waittime INTEGER DEFAULT 10
)
IS
v_msgno INTEGER DEFAULT 0;
v_itemno INTEGER DEFAULT 0;
v_item VARCHAR2(100);
v_status INTEGER;
BEGIN
v_status := DBMS_PIPE.RECEIVE_MESSAGE(p_mailbox,p_waittime);
WHILE v_status = 0 LOOP
v_msgno := v_msgno + 1;
DBMS_OUTPUT.PUT_LINE('****** Start message #' || v_msgno ||
' ******');
BEGIN
LOOP
v_status := DBMS_PIPE.NEXT_ITEM_TYPE;
EXIT WHEN v_status = 0;
DBMS_PIPE.UNPACK_MESSAGE(v_item);
v_itemno := v_itemno + 1;
DBMS_OUTPUT.PUT_LINE('Item #' || v_itemno || ': ' ||
v_item);
END LOOP;
DBMS_OUTPUT.PUT_LINE('******* End message #' || v_msgno ||
' *******');
DBMS_OUTPUT.PUT_LINE('*');
v_itemno := 0;
v_status := DBMS_PIPE.RECEIVE_MESSAGE(p_mailbox,1);
END;
END LOOP;
DBMS_OUTPUT.PUT_LINE('Number of messages received: ' || v_msgno);
v_status := DBMS_PIPE.REMOVE_PIPE(p_mailbox);
IF v_status = 0 THEN
DBMS_OUTPUT.PUT_LINE('Deleted mailbox ' || p_mailbox);
ELSE
DBMS_OUTPUT.PUT_LINE('Could not delete mailbox - status: '
|| v_status);
END IF;
END empty_mailbox;
ENDメールボックス;
最初のストアドプロシージャは、
UNIQUE_SESSION_name関数によって生成された名前を持つパブリックパイプを作成します。
EXEC mailbox.create_mailbox;
次の出力が表示されます。
作成されたメールボックス: PG$PIPE$13$3940
メールボックス名を使用すると、
メールボックスと
DBMS_PIPEパッケージにアクセスできる同じデータベース内のユーザーがメッセージを追加できます。
EXEC mailbox.add_message (「PG$PIPE$13$3940」、「こんにちは、ジョン」、「今日の3時に会議に出席できますか? 」、「 -- Mary」);
EXEC mailbox.add_message (「PG$PIPE$13$3940」、「レポートを送信することを忘れないでください」、「ありがとう」、「 -- Joe」);
次の出力が表示されます。
追加されたメッセージ3アイテムをメールボックスPG$PIPE$13$3940に追加されたメッセージ3アイテムをメールボックスPG$PIPE$13$3940
メールボックスの内容は空になります。
EXEC mailbox.empty_mailbox('PG$PIPE$13$3940 ');
次の出力が表示されます:
****** 開始メッセージ #1 *******
アイテム #1: こんにちは、ジョン
アイテム #2: 今日の3:00に会議に出席できますか?
アイテム #3: -- メアリー
******* メッセージの終了 #1 *******
*
****** スタートメッセージ #2 ******
アイテム #1: レポートを送信することを忘れないでください
アイテム #2: ありがとう、アイテム #3: ジョー
******* メッセージの終了 #2 *******
*
受信したメッセージの数: 2
削除されたメールボックスPG$PIPE$13$3940