您可以使用DBMS_PIPE
包在连接到相同数据库集群的会话内部或者会话之间传递消息。
DBMS_PIPE
不建议集群地址使用,可能引起长事务问题。
下表列出了DBMS_PIPE
包允许使用的函数和存储过程。
表 1. DBMS_PIPE函数/存储过程
函数/存储过程 | 返回类型 | 描述 |
CREATE_PIPE(pipename [, maxpipesize ] [, private ]) | INTEGER | 使用指定的名称显式地创建一个公有或私有管道。 |
NEXT_ITEM_TYPE | INTEGER | 返回缓冲区中下一个数据成员的数据类型。 |
PACK_MESSAGE(item) | 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(item OUT) | N/A | 将本地消息缓冲区中消息的数据项复制到程序变量中。 |
创建管道方式分为显式创建和隐式创建。
隐式创建:引用一个之前不是由函数
CREATE_PIPE
创建的管道名称,会隐式地创建一个管道。例如:如果在执行函数SEND_MESSAGE
时使用了一个之前不存在的管道名称,那么就用这个名称隐式地创建一个管道。说明所有隐式创建的管道均为私有管道。
显式创建:将
CREATE_PIPE
函数的第一个参数指定为新管道的名称,您可以显式地创建一个管道。
管道分为私有管道和公有管道。
只有创建管道的用户才能访问一个私有管道,超级用户不能访问由其他用户创建的管道。
任何能够访问
DBMS_PIPE
包的用户均可以访问公有管道。
通过管道发送消息和接受消息。
通过管道发送消息。第一次在本地消息缓冲区创建的单独数据项或者消息文本行,对于当前会话来说是唯一的。您可以使用存储过程
PACK_MESSAGE
在会话的本地消息缓冲区中创建消息,使用函数SEND_MESSAGE
通过管道发送消息。通过管道接收消息。您首先使用函数
RECEIVE_MESSAGE
从指定的管道中获得消息,再将消息写到会话的本地缓冲区中。然后使用存储过程UNPACK_MESSAGE
将消息的数据成员从消息缓冲区传递给程序变量。如果管道包含多条消息,函数RECEIVE_MESSAGE
以先进先出的顺序接收消息。
存储过程
PACK_MESSAGE
创建的消息和函数RECEIVE_MESSAGE
获取的消息,每一个会话为这两种消息分别保持各自不同的消息缓冲区。可以在相同的会话中创建和接收消息。然而,如果连续执行RECEIVE_MESSAGE
函数, 只有最后一次执行RECEIVE_MESSAGE
函数所获取的消息会保留在本地消息缓冲区中。
使用说明
CREATE_PIPE
语法说明
函数CREATE_PIPE
使用指定的名称显式地创建一个公有或私有管道。语法如下:
status INTEGER CREATE_PIPE(pipename VARCHAR2
[, maxpipesize INTEGER ] [, private BOOLEAN ])
参数
参数名称 | 参数说明 |
pipename | 管道的名称。 |
maxpipesize | 管道的最大容量,以字节为单位。默认值为8192 字节。 |
private |
|
status | 创建管道操作返回的状态代码。0表示成功创建。 |
示例
创建一个名称为
messages
的私有管道:DECLARE v_status INTEGER; BEGIN v_status := DBMS_PIPE.CREATE_PIPE('messages'); DBMS_OUTPUT.PUT_LINE('CREATE_PIPE status: ' || v_status); END;
返回结果如下:
CREATE_PIPE status: 0
创建一个名称为
mailbox
的公有管道:DECLARE v_status INTEGER; BEGIN v_status := DBMS_PIPE.CREATE_PIPE('mailbox',8192,FALSE); DBMS_OUTPUT.PUT_LINE('CREATE_PIPE status: ' || v_status); END;
返回结果如下:
CREATE_PIPE status: 0
NEXT_ITEM_TYPE
语法说明
函数NEXT_ITEM_TYPE
返回一个整数型代码,用于标识消息中下一个数据成员的数据类型。其中,消息应已经送到会话的本地缓冲区中。当您使用存储过程UNPACK_MESSAGE
从本地消息缓冲区移出每一个数据成员时,函数NEXT_ITEM_TYPE
将返回下一个成员的数据类型代码。当在消息中没有成员的时候,将返回代码0。语法如下:
typecode INTEGER NEXT_ITEM_TYPE
参数
参数名称 | 参数说明 |
typecode | 标识消息中下一个数据项的数据类型。详情请参见NEXT_ITEM_TYPE函数返回代码。 |
表 2. NEXT_ITEM_TYPE函数返回代码
返回代码 | 描述 |
0 | 没有数据成员。 |
9 | NUMBER |
11 | VARCHAR2 |
13 | DATE |
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(10) := '21222324'; v_status INTEGER; BEGIN 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 status: ' || v_status); EXCEPTION 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(10); v_status INTEGER; BEGIN 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('---------------------------------'); EXCEPTION WHEN OTHERS THEN DBMS_OUTPUT.PUT_LINE('SQLERRM: ' || SQLERRM); DBMS_OUTPUT.PUT_LINE('SQLCODE: ' || SQLCODE); END;
返回结果如下:
RECEIVE_MESSAGE status: 0 ---------------------------------- NEXT_ITEM_TYPE: 9 NUMBER Item : 123 ---------------------------------- NEXT_ITEM_TYPE: 11 VARCHAR2 Item : Character data ---------------------------------- NEXT_ITEM_TYPE: 13 DATE Item : 02-OCT-07 11:11:43 ---------------------------------- NEXT_ITEM_TYPE: 23 RAW Item : 21222324 ---------------------------------- NEXT_ITEM_TYPE: 0
PACK_MESSAGE
语法说明
PACK_MESSAGE
函数将一个数据项放入会话的本地消息缓冲区中。在使用函数SEND_MESSAGE
前,必须至少执行一次函数PACK_MESSAGE
。语法如下:
PACK_MESSAGE(item { DATE | NUMBER | VARCHAR2 | RAW })
参数
参数名称 | 参数说明 |
item | 用于计算任何可接受数据类型的参数。计算完毕后,会将结果值添加到会话的本地消息缓冲区中。 |
示例
该示例展示了如何通过该存储过程发送不同类型的消息。
该部分只是消息发送的部分,消息接收的部分可以查看UNPACK_MESSAGE的示例。
DECLARE
str VARCHAR2 := 'Character data';
num NUMBER := '1024';
status INTEGER;
BEGIN
DBMS_PIPE.PACK_MESSAGE(str);
DBMS_PIPE.PACK_MESSAGE(num);
-- send message存储过程
status := DBMS_PIPE.SEND_MESSAGE('messages');
END;
PURGE
语法说明
存储过程PURGE
从指定的隐式管道中删除未接收到的消息。语法如下:
PURGE(pipename VARCHAR2)
参数
参数名称 | 参数说明 |
pipename | 管道的名称。 |
示例
在一个管道上发送两条消息:
DECLARE v_status INTEGER; BEGIN 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 status: ' || v_status); END;
返回结果如下:
SEND_MESSAGE status: 0 SEND_MESSAGE status: 0
接收第一条消息,然后打开:
DECLARE v_item VARCHAR2(80); v_status INTEGER; BEGIN 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 status: 0 Item: Message #1
删除管道中的消息:
EXEC DBMS_PIPE.PURGE('pipe');
此时当您尝试取出下一条消息时,函数RECEIVE_MESSAGE会返回状态代码。
DECLARE v_item VARCHAR2(80); v_status INTEGER; BEGIN v_status := DBMS_PIPE.RECEIVE_MESSAGE('pipe',1); DBMS_OUTPUT.PUT_LINE('RECEIVE_MESSAGE status: ' || v_status); END;
返回结果如下,1表示超时,因为这时在管道中没有消息:
RECEIVE_MESSAGE status: 1
RECEIVE_MESSAGE
语法说明
函数RECEIVE_MESSAGE
从指定的管道中获取一条消息。语法如下:
status INTEGER RECEIVE_MESSAGE(pipename VARCHAR2
[, timeout INTEGER ])
参数
参数名称 | 参数说明 |
pipename | 管道的名称。 |
timeout | 等待时间。单位:秒。默认为86400000 s(表示1000 天)。 |
表 3. RECEIVE_MESSAGE
函数返回的状态代码
状态代码 | 描述 |
0 | 成功获取消息。 |
1 | 超时。 |
2 | 对于缓冲区来说管道中的消息太大。 |
3 | 中断。 |
ORA-23322 | 您没有权限获取管道中的消息。 |
REMOVE_PIPE
语法说明
函数REMOVE_PIPE
删除一个显式的私有或公有管道。语法如下:
status INTEGER REMOVE_PIPE(pipename VARCHAR2)
参数
参数名称 | 参数说明 |
pipename | 管道的名称。 |
status | 函数返回的状态代码。即使命名的管道不存在,也会返回状态代码0。 |
示例
在管道中发送两条消息:
DECLARE v_status INTEGER; BEGIN 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 status: ' || v_status); END;
返回结果如下:
CREATE_PIPE status : 0 SEND_MESSAGE status: 0 SEND_MESSAGE status: 0
接收第一条消息,然后打开:
DECLARE v_item VARCHAR2(80); v_status INTEGER; BEGIN 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 status: 0 Item: Message #1
删除管道:
SELECT DBMS_PIPE.REMOVE_PIPE('pipe') FROM DUAL;
返回结果如下:
remove_pipe ------------- 0 (1 row)
当您尝试取回下一条消息,函数
RECEIVE_MESSAGE
将返回状态代码1,表示超时,这是因为管道已经删除。DECLARE v_item VARCHAR2(80); v_status INTEGER; BEGIN v_status := DBMS_PIPE.RECEIVE_MESSAGE('pipe',1); DBMS_OUTPUT.PUT_LINE('RECEIVE_MESSAGE status: ' || v_status); END;
返回结果如下:
RECEIVE_MESSAGE status: 1
RESET_BUFFER
语法说明
存储过程RESET_BUFFER
将会话的本地消息缓冲区中的指针重新设置到缓冲区的开始位置。这样在随后调用PACK_MESSAGE
时,将覆盖在调用存储过程RESET_BUFFER
前在消息缓冲区中已存在的数据项。语法如下:
RESET_BUFFER
示例
将发给
John
的消息写到本地消息缓冲区中。调用存储过程RESET_BUFFER
后,这条信息被发给Bob
的消息覆盖。DECLARE v_status INTEGER; BEGIN DBMS_PIPE.PACK_MESSAGE('Hi, John'); DBMS_PIPE.PACK_MESSAGE('Can you attend a meeting at 3:00, today?'); DBMS_PIPE.PACK_MESSAGE('If not, is tomorrow at 8:30 ok with you?'); DBMS_PIPE.RESET_BUFFER; DBMS_PIPE.PACK_MESSAGE('Hi, Bob'); DBMS_PIPE.PACK_MESSAGE('Can you attend a meeting at 9:30, tomorrow?'); v_status := DBMS_PIPE.SEND_MESSAGE('pipe'); DBMS_OUTPUT.PUT_LINE('SEND_MESSAGE status: ' || v_status); END;
返回结果如下:
SEND_MESSAGE status: 0
在接收到的消息中出现了发给
Bob
的消息。DECLARE v_item VARCHAR2(80); v_status INTEGER; BEGIN 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 status: 0 Item: Hi, Bob Item: Can you attend a meeting at 9:30, tomorrow?
SEND_MESSAGE
语法说明
函数SEND_MESSAGE
从会话的本地消息缓冲区中将一条消息发送到指定的管道。语法如下:
status SEND_MESSAGE(pipename VARCHAR2 [, timeout INTEGER ]
[, maxpipesize INTEGER ])
参数
参数名称 | 参数说明 |
pipename | 管道的名称。 |
timeout | 等待时间,以秒为单位。 默认值为86400000 s(表示1000 天)。 |
maxpipesize | 管道的最大容量,以字节为单位。默认值为8192 字节。 |
表 4. SEND_MESSAGE
函数返回的状态代码
状态代码 | 描述 |
0 | 发送消息成功。 |
1 | 超时。 |
3 | 中断。 |
ORA-23322 | 权限不足。 说明 如果存在同名管道且该管道是由不同用户创建的,则Oracle会发出错误信号ORA-23322,指示命名冲突。 |
示例
该示例用于展示如何将本地的数据发送到管道。
DECLARE
varchar VARCHAR2 := 'Character data';
status INTEGER;
result VARCHAR2;
idx INTEGER;
BEGIN
DBMS_PIPE.PACK_MESSAGE(varchar);
DBMS_PIPE.PACK_MESSAGE(varchar);
DBMS_PIPE.PACK_MESSAGE(varchar);
status := DBMS_PIPE.SEND_MESSAGE('messages');
DBMS_OUTPUT.PUT_LINE('SEND_MESSAGE status is: ' || status);
status := DBMS_PIPE.RECEIVE_MESSAGE('messages');
FOR idx in 1..3 LOOP
DBMS_PIPE.UNPACK_MESSAGE(result);
DBMS_OUTPUT.PUT_LINE(result);
END LOOP;
END;
返回结果如下:
None: SEND_MESSAGE status is: 0
None: Character data
None: Character data
None: Character data
UNIQUE_SESSION_NAME
语法说明
函数UNIQUE_SESSION_NAME
返回当前会话的一个唯一名称。语法如下:
name VARCHAR2 UNIQUE_SESSION_NAME
参数
参数名称 | 参数说明 |
name | 会话的唯一名称。 |
示例
DECLARE
v_session VARCHAR2(30);
BEGIN
v_session := DBMS_PIPE.UNIQUE_SESSION_NAME;
DBMS_OUTPUT.PUT_LINE('Session Name: ' || v_session);
END;
返回结果如下:
Session Name: DBMS_PIPE$35749$
UNPACK_MESSAGE
语法说明
存储过程UNPACK_MESSAGE
将本地消息缓冲区中消息的数据项复制到程序变量中。使用UNPACK_MESSAGE
前,必须先使用函数RECEIVE_MESSAGE
将消息放到本地消息缓冲区中。语法如下:
UNPACK_MESSAGE(item OUT { DATE | NUMBER | VARCHAR2 | RAW })
参数
参数名称 | 参数说明 |
item | 从本地缓冲区中接收数据项的变量,这个变量必须和数据项的类型相兼容。 |
示例
该示例展示了如何接收管道中的消息。
DECLARE
str VARCHAR2;
num NUMBER;
status INTEGER;
BEGIN
-- RECEIVE_MESSAGE status is: 0
status := DBMS_PIPE.RECEIVE_MESSAGE('messages');
DBMS_OUTPUT.PUT_LINE('RECEIVE_MESSAGE status is: ' || status);
-- VARCHAR2 item is: Character data
DBMS_PIPE.UNPACK_MESSAGE(str);
DBMS_OUTPUT.PUT_LINE('VARCHAR2 item is: ' || str);
-- NUMBER item is: 1024
DBMS_PIPE.UNPACK_MESSAGE(num);
DBMS_OUTPUT.PUT_LINE('NUMBER item is: ' || num);
END;
综合性示例
在下面的示例中,将一个管道作为一个“邮箱”。使用存储过程创建邮箱,然后在邮箱中增加一条含有多个数据项的信息(最多有3个数据项)。最后显示
mailbox
包中的全部内容。CREATE OR REPLACE PACKAGE 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 mailbox; CREATE OR REPLACE PACKAGE BODY mailbox 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 mailbox;
第一个存储过程创建了一个公有管道,这个管道的名称是由函数
UNIQUE_SESSION_NAME
生成。EXEC mailbox.create_mailbox;
返回结果如下:
None: Session Name: DBMS_PIPE$35749$
在同一数据库中使用邮箱名称,任何访问
mailbox
包和DBMS_PIPE
的用户都能够添加消息。EXEC mailbox.add_message('DBMS_PIPE$35749$','Hi, John','Can you attend a meeting at 3:00, today?','-- Mary'); EXEC mailbox.add_message('DBMS_PIPE$35749$','Don''t forget to submit your report','Thanks,','-- Joe');
返回结果如下:
Added message with 3 item(s) to mailbox DBMS_PIPE$35749$ Added message with 3 item(s) to mailbox DBMS_PIPE$35749$
清空
mailbox
包中的内容:EXEC mailbox.empty_mailbox('DBMS_PIPE$35749$');
返回结果如下:
****** Start message #1 ****** Item #1: Hi, John Item #2: Can you attend a meeting at 3:00, today? Item #3: -- Mary ******* End message #1 ******* * ****** Start message #2 ****** Item #1: Don't forget to submit your report Item #2: Thanks, Item #3: -- Joe ******* End message #2 ******* * Number of messages received: 2 Deleted mailbox DBMS_PIPE$35749$