Previous Table of Contents Next

The Receive_Message() Function

The Receive_Message() function is used to receive a message from the pipe and place the message in a local buffer. The function has two parameters: pipename and timeout.

FUNCTION Receive_Message (pipename IN     varchar2,
                          timeout  IN     integer := MAXWAIT)
RETURN integer

The pipename parameter holds the name of the pipe. The timeout parameter indicates the period of time that the process will wait for a message to be sent. This parameter defaults to the value of the DBMS_Pipe.MAXWAIT constant (86,400,000 seconds).

The Receive_Message() function returns an integer value indicating its result. The return values for the function are listed in Table 9.3.

Table 9.3 Return values for the Receive_Message( ) function.

Return Value Meaning
0 A message was received.
1 No message was received.
2 The message in the pipe was too large for the buffer.
3 An error occurred.

The Remove_Pipe() Function

The Remove_Pipe() function is called to destroy a pipe created by a call to the Create_Pipe() function. The Remove_Pipe() function has one parameter:

FUNCTION Remove_Pipe (pipename IN     varchar2) RETURN integer

The pipename parameter holds the name of the pipe that is to be deleted. The function will return 0 if the pipe is successfully deleted or if the specified pipe does not exist.

The Send_Message() Function

The Send_Message() function is used to send a message through a pipe. The function accepts one parameter:

FUNCTION Send_Message (pipename IN     varchar2) RETURN integer

The pipename parameter holds the name of the pipe through which the packed message is sent. The function will return one of the integer values shown in Table 9.4.

Table 9.4 Return values of the Send_Message( ) function.

Return Value Meaning
0 The message was successfully sent.
1 The message was not sent due to a timeout.
3 An error occurred while sending the message.

The Unique_Session_Name() Function

The Unique_Session_Name() function returns an integer value that uniquely identifies a particular session connected to Oracle. Each session has its own ID number. Calling this function multiple times from the same session will always yield the same result.

This function is often used to generate a pipename that is specific to a given session. For instance, both session 18 and session 23 might want to create the same pipe, but each session has a unique listener. The Unique_Session_Name() function is called and the resulting value is appended onto the pipe’s name, yielding a uniquely named pipe for each session.

This function has no parameters.

The Unpack_Message() Procedure

The Unpack_Message() procedure is used to extract information from a message. This procedure, like the Pack_Message() procedure, is overloaded. The implementations of the procedure are as follows:

PROCEDURE Unpack_Message (item    OUT varchar2)
PROCEDURE Unpack_Message (item    OUT date)
PROCEDURE Unpack_Message (item    OUT number)
PROCEDURE Unpack_Message (item    OUT raw)
PROCEDURE Unpack_Message (item    OUT ROWID)

Each implementation of the procedure extracts data of a specific type from the message.

Using Pipes

Let’s go back to the order entry system example that we discussed for the DBMS_Alert package. When an order is created or modified, data in a legacy system must be created or modified as well. A trigger is implemented on the ORDERS table that packs a message and sends the message over a pipe. A Pro*C program is implemented to interface with the legacy system and to receive messages over the pipe. Listing 9.2 illustrates how a message can be sent over a pipe.

Listing 9.2 Using a trigger to send a message over a pipe.


   ORDERS_PIPE    CONSTANT varchar2 (30) := 'ORDER';
   iMessageStatus integer;

   DBMS_Pipe.Pack_Message (:new.order_number);
   DBMS_Pipe.Pack_Message (:new.customer_number);
   DBMS_Pipe.Pack_Message (:new.order_cost);

   iMessageStatus := DBMS_Pipe.Send_Message (ORDERS_PIPE);

The Pro*C program is still started by the system when the order entry form is run. This program makes calls to the DBMS_Pipe.Receive_Message() function:

iMessageReceived := DBMS_Pipe.Receive_Message (ORDERS_PIPE);

When iMessageReceived holds a 0 after this call, the program begins calling the DBMS_Pipe.Unpack_Message() procedures to extract individual pieces of data from the message:

IF (iMessageReceived = 0) THEN
   DBMS_Pipe.Unpack_Message (item => iOrderNumber);
   DBMS_Pipe.Unpack_Message (item => iCustomerNumber);
   DBMS_Pipe.Unpack_Message (item => nOrderValue);

In this implementation, the Pro*C program does not have to make a reference back to the ORDERS table to retrieve data. The ORDERS_ARIU trigger can send several messages, and the listener program will process each order in succession, with no loss of data. To implement this type of functionality using signals, the Pro*C program has to refer back to the ORDERS table to query information.

Figure 9.4 illustrates the high-level processing of this implementation.

Figure 9.4  High-level processing of a pipe-based implementation.

Previous Table of Contents Next