dbms_pipe

DBMS_PIPE

DBMS_PIPE包允许同一实例中的两个或多个会话通信。Oracle管道在概念上与UNIX中使用的管道相似,但Oracle管道不是使用操作系统管道机制实现的。

Oracle官方文档:
https://docs.oracle.com/en/database/oracle/oracle-database/21/arpls/DBMS_PIPE.html

管道功能有几个可用的应用领域:
外部服务接口
独立事务
alerts(非事务性)
调试和集中器。

根据您的安全需求,您可以选择使用公共管道或私有管道.

1)、公有管道:所有数据库用户可访问。
2)、私有管道:只能建立管道的数据库用户可访问。

DBMS_PIPE常量

这是尝试发送或接收消息时等待的最长时间。

maxwait   constant integer := 86400000; /* 1000 days */ 

DBMS_PIPE操作说明

通过Oracle管道发送的信息在系统全局区域(SGA)中进行缓冲。当实例关闭时,管道中的所有信息都将丢失。

警告: 管道独立于事务。当事务控制可能受到影响时,要小心使用管道

DBMS_PIPE的操作涉及以下主题:

  • 公共管道(Public Pipes)

  • 写和读管道(Writing and Reading Pipes)

  • 私有管道(Private Pipes)

1. 公共管道(Public Pipes)

您可以隐式或显式地创建公共管道。对于隐式公共管道,管道在第一次被引用时自动创建,当它不再包含数据时消失。因为管道描述符存储在SGA中,所以在空管道从缓存中aged out之前会有一些空间使用开销。

通过调用CREATE_PIPE函数并将private flag设置为FALSE,可以创建显式公共管道。必须通过调用REMOVE_PIPE函数来释放显式创建的管道。

无论是显式创建的还是隐式创建的,公共管道的domain是创建该管道的schema。

2. 写和读管道(Writing and Reading Pipes)

每个公共管道都异步工作。Any number of schema users都可以写入公共管道,只要他们对DBMS_PIPE包有EXECUTE权限,并且知道公共管道的名称。但是,一旦一个用户读取了缓冲的信息,它就会从缓冲区中清空,并且不能用于同一管道的其他读取。

发送会话使用对PACK_MESSAGE过程的一次或多次调用来构建消息。此过程将消息添加到会话的本地消息缓冲区。该缓冲区中的信息通过调用SEND_MESSAGE函数发送,并指定用于发送消息的管道名称。当SEND_MESSAGE被调用时,所有已经在本地缓冲区中堆叠的消息都会被发送。

想要接收消息的进程调用RECEIVE_MESSAGE函数,指定从中接收消息的管道名称。然后,该进程调用UNPACK_MESSAGE过程来访问消息中的每个项。

3. 私有管道(Private Pipes)

通过调用CREATE_PIPE函数显式地创建一个私有管道。私有管道一旦创建,就会一直保存在共享内存中,直到通过调用REMOVE_PIPE函数显式地释放它。当数据库实例关闭时,私有管道也会被释放。

如果内存中存在隐式管道,并且该管道与您试图创建的私有管道具有相同的名称,则无法创建私有管道。在这种情况下,CREATE_PIPE返回一个错误。

对私有管道的访问被限制为:

以与管道创建者相同的用户id运行的会话

与管道创建者在同一用户id特权域中执行的存储子程序

以SYSDBA身份连接的用户

任何其他用户在管道上发送或接收消息或删除管道的尝试都会立即导致错误。其他用户尝试创建具有相同名称的管道也会导致错误。

与公共管道一样,在调用SEND_MESSAGE之前,必须首先使用对PACK_MESSAGE的调用来构建消息。类似地,在通过调用UNPACK_MESSAGE访问消息中的项之前,必须调用RECEIVE_MESSAGE来检索消息。

DBMS_PIPE Exceptions

DBMS_PIPE包子程序可以返回下表中列出的错误。

ORA-23321:

Pipename may not be null. This can be returned by the CREATE_PIPE function, or any subprogram that takes a pipe name as a parameter.

ORA-23322:

Insufficient privilege to access pipe. This can be returned by any subprogram that references a private pipe in its parameter list.

DBMS_PIPE Examples

这个例子展示了PL/SQL程序可以调用的将调试信息放置在管道中的过程。

CREATE OR REPLACE PROCEDURE debug (msg VARCHAR2) AS
    status  NUMBER;
BEGIN
  DBMS_PIPE.PACK_MESSAGE(LENGTH(msg));
  DBMS_PIPE.PACK_MESSAGE(msg);
  status := DBMS_PIPE.SEND_MESSAGE('plsql_debug');
  IF status != 0 THEN
    raise_application_error(-20099, 'Debug error');
  END IF;
END debug;

Summary of DBMS_PIPE Subprograms

该表列出了DBMS_PIPE子程序并简要描述了它们。

SubprogramDescription
CREATE_PIPE FunctionCreates a pipe (necessary for private pipes)
NEXT_ITEM_TYPE FunctionReturns datatype of next item in buffer
PACK_MESSAGE ProceduresBuilds message in local buffer
PURGE ProcedurePurges contents of named pipe
RECEIVE_MESSAGE FunctionCopies message from named pipe into local buffer
REMOVE_PIPE FunctionRemoves the named pipe
RESET_BUFFER ProcedurePurges contents of local buffer
SEND_MESSAGE FunctionSends message on named pipe: This implicitly creates a public pipe if the named pipe does not exist
UNIQUE_SESSION_NAME FunctionReturns unique session name
UNPACK_MESSAGE ProceduresAccesses next item in buffer
1. CREATE_PIPE Function

这个函数显式地创建一个公共或私有管道。如果private标志为TRUE,则管道创建者被指定为私有管道的所有者。

只能通过调用REMOVE_PIPE或关闭实例来删除显式创建的管道。

语法

DBMS_PIPE.CREATE_PIPE (
   pipename     IN VARCHAR2,
   maxpipesize  IN INTEGER DEFAULT 8192,
   private      IN BOOLEAN DEFAULT TRUE)
RETURN INTEGER;

参数

ParameterDescription
pipenameName of the pipe you are creating.You must use this name when you call SEND_MESSAGE and RECEIVE_MESSAGE. This name must be unique across the instance.Caution: Do not use pipe names beginning with ORA$. These are reserved for use by procedures provided by Oracle. Pipename should not be longer than 128 bytes, and is case insensitive. At this time, the name cannot contain Globalization Support characters.
maxpipesizeThe maximum size allowed for the pipe, in bytes.The total size of all of the messages on the pipe cannot exceed this amount. The message is blocked if it exceeds this maximum. The default maxpipesize is 8192 bytes.The maxpipesize for a pipe becomes a part of the characteristics of the pipe and persists for the life of the pipe. Callers of SEND_MESSAGE with larger values cause the maxpipesize to be increased. Callers with a smaller value use the existing, larger value.
privateUses the default, TRUE, to create a private pipe.Public pipes can be implicitly created when you call SEND_MESSAGE.

返回值

ReturnDescription
0Successful.If the pipe already exists and the user attempting to create it is authorized to use it, then Oracle returns 0, indicating success, and any data already in the pipe remains.If a user connected as SYSDBA/SYSOPER re-creates a pipe, then Oracle returns status 0, but the ownership of the pipe remains unchanged.
ORA-23322Failure due to naming conflict.If a pipe with the same name exists and was created by a different user, then Oracle signals error ORA-23322, indicating the naming conflict.

异常

ExceptionDescription
Null pipe namePermission error: Pipe with the same name already exists, and you are not allowed to use it.
2. NEXT_ITEM_TYPE Function

此函数确定本地消息缓冲区中下一项的数据类型。

在调用RECEIVE_MESSAGE将管道信息放入本地缓冲区之后,调用NEXT_ITEM_TYPE。

语法

DBMS_PIPE.NEXT_ITEM_TYPE 
  RETURN INTEGER; 

返回值

ReturnDescription
0No more items
6NUMBER
9VARCHAR2
11ROWID
12DATE
23RAW
3. PACK_MESSAGE Procedures

在本地消息缓冲区中构建消息。

要发送消息,首先对PACK_MESSAGE进行一次或多次调用。然后,调用SEND_MESSAGE在命名管道上的本地缓冲区中发送消息。

该过程被重载以接受VARCHAR2、NCHAR、NUMBER、DATE,RAW和ROWID类型。除了数据字节之外,缓冲区中的每个项还需要一个字节来表示其类型,两个字节来存储其长度。需要一个额外的字节来终止消息。除了VARCHAR以外的所有类型的开销都是4字节。

语法

DBMS_PIPE.PACK_MESSAGE (
   item  IN  VARCHAR2);

DBMS_PIPE.PACK_MESSAGE (
   item  IN  NCHAR);

DBMS_PIPE.PACK_MESSAGE (
   item  IN  NUMBER);

DBMS_PIPE.PACK_MESSAGE (
   item  IN  DATE);

DBMS_PIPE.PACK_MESSAGE_RAW (
   item  IN  RAW);

DBMS_PIPE.PACK_MESSAGE_ROWID (
   item  IN  ROWID);

当您调用SEND_MESSAGE来发送此消息时,必须指出要在其上发送消息的管道的名称。如果这个管道已经存在,那么您必须有足够的权限来访问这个管道。如果管道不存在,则会自动创建它。

异常

如果消息缓冲区溢出(当前为4096字节),将引发ORA-06558。缓冲区中的每个项都用一个字节表示类型,两个字节表示长度,再加上实际数据。还需要一个字节来终止消息。

4. PURGE Procedure

此过程将清空命名管道的内容。

根据最近最少使用的算法,将隐式创建的空管道从共享全局区域中aged out。因此,调用PURGE可以释放与隐式创建的管道相关的内存。

语法

DBMS_PIPE.PURGE (
   pipename  IN  VARCHAR2);

参数

| Parameter  | Description                                                  |
| :--------- | :----------------------------------------------------------- |
| `pipename` | Name of pipe from which to remove all messages.The local buffer may be overwritten with messages as they are discarded. Pipename should not be longer than 128 bytes, and is case-insensitive. |

因为PURGE调用了RECEIVE_MESSAGE,所以在从管道中清除消息时,本地缓冲区可能会被消息覆盖。此外,如果您试图清除您没有足够访问权限的管道,您可能会收到ORA-23322(特权不足)错误。

异常

如果管道属于其他用户,则权限错误。

5. RECEIVE_MESSAGE Function

这个函数将消息复制到本地消息缓冲区中。

语法

DBMS_PIPE.RECEIVE_MESSAGE (
   pipename     IN VARCHAR2,
   timeout      IN INTEGER      DEFAULT maxwait)
RETURN INTEGER;

参数

ParameterDescription
pipenameName of the pipe on which you want to receive a message.Names beginning with ORA$ are reserved for use by Oracle
timeoutTime to wait for a message, in seconds.The default value is the constant MAXWAIT, which is defined as 86400000 (1000 days). A timeout of 0 lets you read without blocking.

返回值

ReturnDescription
0Success
1Timed out. If the pipe was implicitly-created and is empty, then it is removed.
2Record in the pipe is too large for the buffer. (This should not happen.)
3An interrupt occurred.
ORA-23322User has insufficient privileges to read from the pipe.

要从管道接收消息,首先调用RECEIVE_MESSAGE。当你收到一条消息时,它被从管道中移除;因此,一条消息只能被接收一次。对于隐式创建的管道,将在从管道中删除最后一条记录后删除管道。

如果调用RECEIVE_MESSAGE时指定的管道不存在,那么Oracle将隐式创建该管道并等待接收消息。如果消息没有在指定的超时间隔内到达,则调用返回并删除管道。

收到消息后,必须对UNPACK_MESSAGE进行一次或多次调用,以访问消息中的各个项目。UNPACK_MESSAGE过程被重载以解包DATE、NUMBER、VARCHAR2类型的项目,另外还有两个过程用于解包RAW和ROWID项目。如果不知道要解包的数据类型,则调用NEXT_ITEM_TYPE来确定缓冲区中下一项的类型。

异常

ExceptionDescription
Null pipe namePermission error. Insufficient privilege to remove the record from the pipe. The pipe is owned by someone else.
6. RESET_BUFFER Procedure

将PACK_MESSAGE和UNPACK_MESSAGE重置为0。

因为所有管道都共享一个缓冲区,所以会发现在使用新管道之前重置缓冲区非常有用。这确保了第一次尝试向管道发送消息时,不会无意中发送缓冲区中剩余的过期消息。

语法

DBMS_PIPE.RESET_BUFFER; 
7. REMOVE_PIPE Function

这个函数删除显式创建的管道。

由SEND_MESSAGE隐式创建的管道在为空时自动删除。然而,由CREATE_PIPE显式创建的管道只能通过调用REMOVE_PIPE或关闭实例来删除。在删除管道之前,将删除管道中所有未使用的记录。

这类似于在隐式创建的管道上调用PURGE。

语法

DBMS_PIPE.REMOVE_PIPE (
   pipename  IN  VARCHAR2)
RETURN INTEGER;

参数

ParameterDescription
pipenameName of pipe that you want to remove.

返回值

ReturnDescription
0SuccessIf the pipe does not exist, or if the pipe already exists and the user attempting to remove it is authorized to do so, then Oracle returns 0, indicating success, and any data remaining in the pipe is removed.
ORA-23322Insufficient privileges.If the pipe exists, but the user is not authorized to access the pipe, then Oracle signals error ORA-23322, indicating insufficient privileges.
8. SEND_MESSAGE Function

这个函数在命名管道上发送消息。

消息包含在本地消息缓冲区中,该缓冲区由对PACK_MESSAGE的调用填充。您可以使用CREATE_PIPE显式地创建管道,否则将隐式地创建管道。

语法

DBMS_PIPE.SEND_MESSAGE (
    pipename     IN VARCHAR2,
    timeout      IN INTEGER DEFAULT MAXWAIT,
    maxpipesize  IN INTEGER DEFAULT 8192)
  RETURN INTEGER;

参数

ParameterDescription
pipenameName of the pipe on which you want to place the message.If you are using an explicit pipe, then this is the name that you specified when you called CREATE_PIPE.Caution: Do not use pipe names beginning with ‘ORA$’. These names are reserved for use by procedures provided by Oracle. Pipename should not be longer than 128 bytes, and is case-insensitive. At this time, the name cannot contain Globalization Support characters.
timeoutTime to wait while attempting to place a message on a pipe, in seconds.The default value is the constant MAXWAIT, which is defined as 86400000 (1000 days).
maxpipesizeMaximum size allowed for the pipe, in bytes.The total size of all the messages on the pipe cannot exceed this amount. The message is blocked if it exceeds this maximum. The default is 8192 bytes.The maxpipesize for a pipe becomes a part of the characteristics of the pipe and persists for the life of the pipe. Callers of SEND_MESSAGE with larger values cause the maxpipesize to be increased. Callers with a smaller value simply use the existing, larger value.Specifying maxpipesize as part of the SEND_MESSAGE procedure eliminates the need for a separate call to open the pipe. If you created the pipe explicitly, then you can use the optional maxpipesize parameter to override the creation pipe size specifications.

返回值

ReturnDescription
0Success.If the pipe already exists and the user attempting to create it is authorized to use it, then Oracle returns 0, indicating success, and any data already in the pipe remains.If a user connected as SYSDBS/SYSOPER re-creates a pipe, then Oracle returns status 0, but the ownership of the pipe remains unchanged.
1Timed out.This procedure can timeout either because it cannot get a lock on the pipe, or because the pipe remains too full to be used. If the pipe was implicitly-created and is empty, then it is removed.
3An interrupt occurred.If the pipe was implicitly created and is empty, then it is removed.
ORA-23322Insufficient privileges.If a pipe with the same name exists and was created by a different user, then Oracle signals error ORA-23322, indicating the naming conflict.
9. UNIQUE_SESSION_NAME Function

此函数接收一个名称,该名称在当前连接到数据库的所有会话中是唯一的。

同一会话中对该函数的多次调用总是返回相同的值。您可能会发现使用这个函数为SEND_MESSAGE和RECEIVE_MESSAGE调用提供PIPENAME参数是很有用的。

语法

DBMS_PIPE.UNIQUE_SESSION_NAME 
  RETURN VARCHAR2;

返回值

这个函数返回一个唯一的名称。返回的名称最大可达30字节。

10. UNPACK_MESSAGE Procedures

这个过程从缓冲区中检索项。

在调用RECEIVE_MESSAGE将管道信息放入本地缓冲区之后,调用UNPACK_MESSAGE。

UNPACK_MESSAGE过程被重载以返回VARCHAR2、NCHAR、NUMBER或DATE类型的项。还有两个额外的过程来解包RAW和ROWID项目。

DBMS_PIPE.UNPACK_MESSAGE (
   item  OUT VARCHAR2);

DBMS_PIPE.UNPACK_MESSAGE (
   item  OUT NCHAR);

DBMS_PIPE.UNPACK_MESSAGE (
   item  OUT NUMBER);

DBMS_PIPE.UNPACK_MESSAGE (
   item  OUT DATE);

DBMS_PIPE.UNPACK_MESSAGE_RAW (
   item  OUT RAW);

DBMS_PIPE.UNPACK_MESSAGE_ROWID (
   item  OUT ROWID);

异常

ORA-06556或06559是在缓冲区不包含任何项目,或者项目与请求的类型不同的情况下生成的。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值