Previous | Table of Contents | Next

Page 474

You should use these return codes for proper error checking and error handling.

Using the RECEIVE_MESSAGE Function
The RECEIVE_MESSAGE function moves a message from the pipe to the message buffer. Then the datatype can be identified with NEXT_ITEM_TYPE, or you could use UNPACK_MESSAGE to read the message buffer and use in your process.

The Syntax for the RECEIVE_MESSAGE Function
The format for RECEIVE_MESSAGE is

FUNCTION RECEIVE_MESSAGE(name_of_pipe IN VARCHAR2,
                    timeout IN INTEGER DEFAULT maxwait);
RETURN INTEGER;

name_of_pipe is the name of the pipe already in existence. timeout is how long it will attempt to read the next line from the pipe if there are no current messages in the pipe. The possible return codes are listed in Table 19.9.

Table 19.9. Return values from RECEIVE_MESSAGE.

Return Code Meaning
0 The message was received successfully.
1 The maximum wait time has been exceeded while waiting for a message to be sent to the pipe.
2 The message in the pipe is too big for the message buffer. This should never occur because both SEND_MESSAGE and RECEIVE_MESSAGE buffers are limited to the same length of
4096 bytes. 3
The message being received was interrupted.

The UNPACK_MESSAGE Procedure
After you have received a message in the buffer, you need to move the message from the buffer into a variable. This is done through the use of the UNPACK_MESSAGE procedure. As with the PACK_MESSAGE procedure, the UNPACK_MESSAGE procedure is overloaded, and can accept such datatypes as VARCHAR2, DATE, and NUMBER.

The Syntax for the UNPACK_MESSAGE Procedure
The syntax of the procedure is

PROCEDURE UNPACK_MESSAGE(data OUT VARCHAR2);
PROCEDURE UNPACK_MESSAGE(data OUT DATE);
PROCEDURE UNPACK_MESSAGE(data OUT NUMBER);

Page 475

data is the data that you are receiving from the message buffer. You can receive two possible errors when trying to unpack the message, which are

ORA-06556 the pipe is empty, cannot fulfill the UNPACK_MESSAGE request
ORA-06559 wrong datatype requested, datatype, actual datatype is datatype

Both can be handled through error message handlers. The first error occurs when you try to read the message buffer, which is empty. The second error message says that the datatype that you are requesting is a different datatype than the one stored in the pipe. You would most likely not have this problem if the datatype in the pipe is always the same, but if it can vary, you would use the NEXT_ITEM_TYPE function to determine the datatype of the next item in the buffer before you retrieve it.

The format for NEXT_ITEM_TYPE function is

FUNCTION NEXT_ITEM_TYPE RETURN INTEGER;

There are no parameters required to send to the function. It returns a value of the datatype, which is listed in Table 19.10.

Table 19.10. Return datatype definitions from NEXT_ITEM_TYPE.

Return Code Description
0 No more items
6 NUMBER
9 VARCHAR2
11 ROWID
12 DATE
13 RAW

You can use the NEXT_ITEM_TYPE function for exception handling for no data in the pipe, as well as for determining the type of data being passed to you from the message buffer. This can easily be implemented with a series of IF...ELSIF statements.

The REMOVE_PIPE Function
After you no longer need a pipe, you can either wait for the system to eventually delete the pipe, or you can use the REMOVE_PIPE function.

The Syntax for the REMOVE_PIPE Function The syntax for the function is

FUNCTION REMOVE_PIPE(name_of_pipe IN VARCHAR2);
RETURN INTEGER; -- Status on pipe deletion

Page 476

The return value is 0 whether the pipe exists or not. The only exception you will receive is ORA-23322, which means that you don't have access to remove the pipe. When a pipe is removed, all messages stored in the pipe are also deleted.

An Example of Using Pipes

This section demonstrates the use of pipes by creating both a public and a private pipe and then extracting the data from both pipes and displaying it to the screen.

Creating Public and Private Pipes
To create the public and private pipes, enter and execute the code in Listing 19.21. Before you execute the code, make sure that you type SET SERVEROUTPUT ON to see output from the DBMS_OUTPUT package.

INPUTListing 19.21. Creating pipes.

 1: DECLARE
 2:      v_statpipe1 integer; -- Status for private pipe
 3:      v_statpipe2 integer; -- Status for public pipe created on-the-fly
 4:      v_pubchar VARCHAR2(100) := `This is a text string';
 5:      v_pubdate DATE := SYSDATE;
 6:      v_pubnum NUMBER := 109;
 7: BEGIN
 8: -- Creates Private Pipe
 9:      v_statpipe1 := DBMS_PIPE.CREATE_PIPE(`myprivatepipe');
10: -- If the pipe was successfully created
11:      IF (v_statpipe1 = 0) THEN
12:           DBMS_PIPE.PACK_MESSAGE(`privateline1');
13:           DBMS_PIPE.PACK_MESSAGE(`privateline2');
14: -- Send Message Buffer to Private Pipe
15:           v_statpipe1 := DBMS_PIPE.SEND_MESSAGE(`myprivatepipe');
16:      END IF;
17:
18:      DBMS_PIPE.PACK_MESSAGE(v_pubchar); -- sends datatype VARCHAR2
19:      DBMS_PIPE.PACK_MESSAGE(v_pubdate); -- sends datatype DATE
20:      DBMS_PIPE.PACK_MESSAGE(v_pubnum);  -- sends datatype NUMBER
21: --Creates public pipe and sends message buffer to the pipe
22:      v_statpipe2 := DBMS_PIPE.SEND_MESSAGE(`mypublicpipe');
23: --Check status of both pipes to make sure they're 0 (created properly)
24:      DBMS_OUTPUT.PUT_LINE(`The Status of your Private Pipe is: ` ||
25:           v_statpipe1 );
26:      DBMS_OUTPUT.PUT_LINE(`The Status of your Public Pipe is: ` ||
27:           v_statpipe2 );
28:
29: END;

After the code has executed, if you have all permissions to the DBMS_PIPE package, then you should see the following output:

Page 477

OUTPUT
The Status of your Private Pipe is: 0
The Status of your Public Pipe is: 0
ANALYSIS In this example, the program first creates a private pipe called myprivatepipe in line 9. It then sends two messages of type VARCHAR2 to the message buffer and then uses SEND_MESSAGE in line 15 to output the buffer to the pipe. The only error checking done here is to make sure that the private pipe is created properly in line 11. Ideally, you should check for overflows of the message buffer and whether the data was sent to the pipe (pipe not full, and so on).

The program then sends more data to the message buffer of type VARCHAR2, DATE, and NUMBER in lines 18 through 20, and upon execution of SEND_MESSAGE in line 22, it creates the public pipe mypublicpipe. The DBMS_OUTPUT package will then display the status of the newly created pipes in lines 24 through 27.

Reading Data from the Pipes You can now prepare to read data from both pipes. Enter and execute the code in Listing 19.22. Again, make sure that you have typed SET SERVEROUTPUT ON for proof that the pipes worked.

INPUTListing 19.22. Reading data from the private and public pipe.

 1: DECLARE
 2:      v_statpipe1 integer; -- status of private pipe
 3:      v_statpipe2 integer; -- status of public pipe
 4:      v_holdtype INTEGER; -- holds status of next item type
 5:      v_holdchar VARCHAR2(100);
 6:      v_holddate DATE;
 7:      v_holdnum NUMBER;
 8: BEGIN
 9: -- start procedure of getting message from private pipe
10:      v_statpipe1 := DBMS_PIPE.RECEIVE_MESSAGE(`myprivatepipe',15);
11:      DBMS_PIPE.UNPACK_MESSAGE(v_holdchar);
12:      DBMS_OUTPUT.PUT_LINE(v_holdchar);--display 1st datatype from msg
13:      DBMS_PIPE.UNPACK_MESSAGE(v_holdchar);
14:      DBMS_OUTPUT.PUT_LINE(v_holdchar);--display 2nd datatype from msg
15:
16: -- start procedure of getting message from public pipe
17:      v_statpipe2 := DBMS_PIPE.RECEIVE_MESSAGE(`mypublicpipe',10);
18:      LOOP
19:           v_holdtype := DBMS_PIPE.NEXT_ITEM_TYPE;
20:           IF v_holdtype = 0 THEN EXIT;
21:           ELSIF v_holdtype = 6 THEN
22:                DBMS_PIPE.UNPACK_MESSAGE(v_holdnum);
23:           ELSIF v_holdtype = 9 THEN
24:                DBMS_PIPE.UNPACK_MESSAGE(v_holdchar);
25:           ELSIF v_holdtype = 12 THEN
26:                DBMS_PIPE.UNPACK_MESSAGE(v_holddate);
27:           END IF;
                                                 continues

Previous | Table of Contents | Next

Используются технологии uCoz