DBMS_PIPE 包

DBMS_PIPE包用于同一实例的不同会话之间通过管道进行通信。这里的管道(PIPE)类似于UNIX系统的管道,但它不是采用操作系统机制实现的。管道信息被存储在本地消息缓冲区中,当关闭实例时会丢失管道信息。

管道的发送端和接收端都有相应的本地消息缓冲区进行接收和发送消息。DBMS_PIPE包中函数的使用流程大致为:首先,发送端创建(CREATE_PIPE)管道、打包(PACK_MESSAGE)管道消息、发送(SEND_MESSAGE)消息;其次,接收端接收(RECEIVE_MESSAGE)消息、取出(UNPACK_MESSAGE)消息。

14.1 相关方法

  1. CREATE_PIPE

显式创建一个公用或者私有管道。

语法如下:

DBMS_PIPE.CREATE_PIPE(

	pipename IN VARCHAR2,

	maxpipesize IN INTEGER DEFAULT 8192,

	IS_private IN BOOLEAN DEFAULT TRUE

)RETURN INTEGER;

参数详解

  • pipename指定管道的名称。
  • maxpipesize指定管道消息的最大尺寸。取值范围:8K~2G。
  • IS_private

指定管道类型。TRUE表示建立私有管道,FALSE建立公有管道。公用管道是指所有数据库用户都可以访问的管道,而私有管道只有建立管道的数据库用户才能访问。

返回值

如果该函数返回0,则表示建立管道成功,否则表示建立管道失败。

使用说明:

通过CREATE_PIPE创建的管道的方法为显式创建;在向指定的管道发送消息的过程中,如果指定的管道不存在,则系统会隐式创建管道,这种方法称为隐式创建。

  1. NEXT_ITEM_TYPE

获取本地消息缓冲区中下一条消息的数据类型,在调用了RECEIVE_MESSAGE之后调用该函数。

语法如下:

DBMS_PIPE. NEXT_ITEM_TYPE RETURN INTEGER;

返回值

返回0,则表示管道没有任何消息。

返回6,则表示下一项的数据类型为NUMBER。

返回9,则表示下一项的数据类型为VARCHAR2。

返回12,则表示下一项的数据类型为DATE。

返回23,则表示下一项的数据类型为BINARY。

  1. REMOVE_PIPE

删除指定的管道。

语法如下:

DBMS_PIPE.REMOVE_PIPE (

	pipename IN VARCHAR2

)RETURN INTEGER;

参数详解

  • pipename管道名称。

使用说明:

  1. 对于隐式创建的管道来说,管道为空时自动被删除,不需要调用该函数。
  2. 对于显式创建的管道来说,只能通过调用REMOVE_PIPE或者关闭数据库实例来删除管道。

返回值

0:删除成功

其他错误码:删除失败

  1. RESET_BUFFER

清空本地发送消息缓冲区。因为一个会话中所有的管道都共享一个本地管道缓冲区,所以为防止将本地缓存中原有的数据发送到管道中,在发送消息之前应该复位管道缓冲区。

语法如下:

DBMS_PIPE.RESET_BUFFER;
  1. PURGE

清空指定管道中的消息。

语法如下:

DBMS_PIPE.PURGE (

	pipename IN VARCHAR2

);

参数详解

  • pipename管道名称。
  1. PACK_MESSAGE

在本地消息缓冲区中指定消息打包。

为了给管道发送信息,首先需要使用过程PACK_MESSAGE将本地消息缓冲区中的指定消息打包好,然后使用过程SEND_MESSAGE将打包好的消息发送到管道。

语法如下:

DBMS_PIPE.PACK_MESSAGE (item IN VARCHAR);

DBMS_PIPE.PACK_MESSAGE (item IN INT);

DBMS_PIPE.PACK_MESSAGE (item IN BIGINT);

DBMS_PIPE.PACK_MESSAGE (item IN DOUBLE);

DBMS_PIPE.PACK_MESSAGE (item IN NUMBER);

DBMS_PIPE.PACK_MESSAGE (item IN DATE);

DBMS_PIPE.PACK_MESSAGE_ROWID (item IN BIGINT);

参数详解

  • item指定管道消息。其输入值可以是字符,数字,日期等多种数据类型。
  1. RECEIVE_MESSAGE

接收指定管道中的消息到本地消息缓冲区。

语法如下:

DBMS_PIPE.RECEIVE_MESSAGE (

	pipename IN VARCHAR2,

	timeout IN INTEGER DEFAULT maxwait

)RETURN INTEGER;

参数详解

  • pipename管道名称。
  • timeout最大等待时间。取值范围:0~86400000单位:秒。

返回值

返回0,表示接收消息成功。

返回1,则表示出现超时。

返回2,则表示本地缓冲区不能容纳管道消息。

返回3,则表示发生中断。

使用说明:

  1. 接收之后,消息从管道删除。
  2. 一条消息只能被接收一次。
  3. 对于隐式创建的管道来说,管道中最后一条消息被删除后,该管道被自动删除。
  1. SEND_MESSAGE

向指定管道上发送一条消息。

语法如下:

DBMS_PIPE.SEND_MESSAGE (

	pipename IN VARCHAR2,

	timeout IN INTEGER DEFAULT MAXWAIT,

	maxpipesize IN INTEGER DEFAULT 8192

) RETURN INTEGER;

参数详解

  • pipename管道名称。
  • timeout最大等待时间。取值范围:0~86400000单位:秒。
  • maxpipesize指定管道消息的最大尺寸。取值范围:8K~2G。

使用说明:

  1. 消息是通过调用PACK_MESSAGE生成并存储在本地缓冲区内。
  2. 如果指定的管道不存在,则自动隐式创建。

返回值

返回0,表示接收消息成功。

返回1,表示出现超时。

返回2,则表示本地缓冲区不能容纳管道消息。

返回3,则表示发生中断。

  1. UNIQUE_SESSION_NAME

返回一个会话的唯一标示名称。对于同一会话来说,其值不会改变。

语法如下:

DBMS_PIPE.UNIQUE_SESSION_NAME

RETURN VARCHAR2;
  1. UNPACK_MESSAGE

用于取出消息缓冲区中的内容。在使用函数RECEIVE_MESSAGE将管道消息接收到本地消息缓冲区中之后,应该使用过程UNPACK_MESSAGE取得本地消息缓冲区的消息。

当使用过程UNPACK_MESSAGE取出消息缓冲区的消息时,每次只能取出一条消息。如果要取出多条消息,则需要多次调用过程UNPACK_MESSAGE。

语法如下:

DBMS_PIPE.UNPACK_MESSAGE (item OUT VARCHAR2);

DBMS_PIPE.UNPACK_MESSAGE (item OUT INT);

DBMS_PIPE.UNPACK_MESSAGE (item OUT BIGINT);

DBMS_PIPE.UNPACK_MESSAGE (item OUT DOUBLE);

DBMS_PIPE.UNPACK_MESSAGE (item OUT NUMBER);

DBMS_PIPE.UNPACK_MESSAGE (item OUT DATE);

DBMS_PIPE.UNPACK_MESSAGE_ROWID (item OUT BIGINT);

参数详解

  • item 指定管道消息,其输入值可以是字符,数字,日期等多种数据类型。

14.2 动态视图

V$DB_PIPES

记录管道的相关信息。

列名 类型 说明
NAME VARCHAR(30) NOT NULL 管道的名字
OWNERID BIGINT NOT NULL 管道拥有者ID
TYPE VARCHAR(7) 管道类型:PUBLIC/PRIVATE
PIPE_SIZE BIGINT 管道的长度

14.3 举例说明

使用包内的过程和函数之前,如果还未创建过系统包。请先调用系统过程创建系统包。

SP_CREATE_SYSTEM_PACKAGES (1,'DBMS_PIPE');

SP_CREATE_SYSTEM_PACKAGES (1,'DBMS_OUTPUT');

SET SERVEROUTPUT ON; --dbms_output.put_line需要设置这条语句,才能打印出消息

举一个两个会话之间通信的实例。

第一步,第一个会话发送消息。该会话连接的用户名和密码为SYSDBA/SYSDBA。

declare

v_pipename varchar2(30):='pipe2';

v_status integer;

begin

DBMS_PIPE.PURGE(v_pipename);

DBMS_PIPE.RESET_BUFFER;

v_status:=DBMS_PIPE.create_pipe(v_pipename,8192,FALSE);

if v_status !=0 then

raise_application_error(-20099, 'create_pipe error status = '|| v_status);

end if;

dbms_pipe.pack_message(' hello,this is sending process!');

v_status:=dbms_pipe.send_message(v_pipename);

if v_status !=0 then

dbms_output.put_line('error!');

end if;

end;

/

第二步,第二个会话接收消息。该会话连接的用户名和密码为USER01/USER012345。

declare

v_pipename varchar2(30):='pipe2';

v_status integer;

v_msg varchar2(20);

begin

v_status:=dbms_pipe.receive_message(v_pipename);

if v_status !=0 then

dbms_output.put_line('error');

end if;

dbms_pipe.unpack_message(v_msg);

print v_msg;

end;

/

结果打印出:hello,this is sending process!

微信扫码
分享文档
扫一扫
联系客服