1. Trang chủ
  2. » Công Nghệ Thông Tin

Oracle Built−in Packages- P37 potx

5 225 0

Đang tải... (xem toàn văn)

THÔNG TIN TÀI LIỆU

Thông tin cơ bản

Định dạng
Số trang 5
Dung lượng 78,66 KB

Nội dung

,private_IN IN BOOLEAN DEFAULT TRUE) RETURN BOOLEAN; /* || encapsulates DBMS_PIPE.REMOVE_PIPE and returns || FALSE if ORA−23322 is raised, indicating || the pipename exists and is not removable || by the caller */ FUNCTION closepipe (pipename_IN IN VARCHAR2) RETURN BOOLEAN; /* || purges all pipes the caller can access */ PROCEDURE purge_all_pipes; END dbpipe; 3.1.7.3.1 Unpack_to_tbl and pack_from_tbl procedures The two procedures unpack_to_tbl and pack_from_tbl implement the generic unpack and pack functionality. They use PL/SQL tables of records based on message_tbltype, which is designed to hold an ordered list of items of any datatype. Each row in a table of type message_tbltype contains two data values: an entry in the item_type field indicating the type of this message item (as returned by DBMS_PIPE.NEXT_ITEM_TYPE) and an entry in the field of the corresponding datatype with the value of this message item. The unpack_to_tbl procedure unpacks all items in a newly received message into a message table, indexing them in the table by their unpack order. The pack_from_tbl procedure takes a message table loaded in this fashion and repacks the original message into the message buffer in index order. The unpack_to_tbl procedure can also optionally use the DBMS_OUTPUT built−in package (described in Chapter 6, Generating Output from PL/SQL Programs) to display the message unpacked. Here are the full package bodies for unpack_to_tbl and pack_from_tbl. Note how unpack_to_tbl grew out of the example code for the DBMS.PIPE.NEXT_ITEM_TYPE function. /* Filename on companion disk: dbpipe.sql */* PROCEDURE unpack_to_tbl (message_tbl_OUT OUT message_tbltype ,display_TF IN BOOLEAN := FALSE) IS /* || NOTE: this procedure should only be called after || a successful call to DBMS_PIPE.RECEIVE_MESSAGE */ /* empty table to flush output table on exception */ null_message_tbl message_tbltype; /* || temp display variable extra long to account || for RAWTOHEX conversion that can double size */ temp_varchar2 VARCHAR2(8186); next_item INTEGER; item_count INTEGER := 0; BEGIN next_item := DBMS_PIPE.NEXT_ITEM_TYPE; /* [Appendix A] What's on the Companion Disk? 3.1.7 DBMS_PIPE Examples 171 || loop through all items, unpacking each by item || type and convert to varchar2 for display */ WHILE next_item > 0 LOOP /* || increment item count and store item type */ item_count := item_count + 1; message_tbl_OUT(item_count).item_type := next_item; /* || now use next_item to call correct unpack procedure, || saving item to message_tbl || || also stuff temp_varchar2 with string conversion || of the item */ IF next_item = 9 THEN DBMS_PIPE.UNPACK_MESSAGE (message_tbl_OUT(item_count).Mvarchar2); temp_varchar2 := 'VARCHAR2: '|| message_tbl_OUT(item_count).Mvarchar2; ELSIF next_item = 6 THEN DBMS_PIPE.UNPACK_MESSAGE (message_tbl_OUT(item_count).Mnumber); temp_varchar2 := 'NUMBER: '|| TO_CHAR(message_tbl_OUT(item_count).Mnumber); ELSIF next_item = 11 THEN DBMS_PIPE.UNPACK_MESSAGE_ROWID (message_tbl_OUT(item_count).Mrowid); temp_varchar2 := 'ROWID: '|| ROWIDTOCHAR(message_tbl_OUT(item_count).Mrowid); ELSIF next_item = 12 THEN DBMS_PIPE.UNPACK_MESSAGE (message_tbl_OUT(item_count).Mdate); temp_varchar2 := 'DATE: '|| TO_CHAR(message_tbl_OUT(item_count).Mdate, 'YYYY:MM:DD:HH24:MI:SS'); ELSIF next_item = 23 THEN DBMS_PIPE.UNPACK_MESSAGE_RAW (message_tbl_OUT(item_count).Mraw); temp_varchar2 := 'RAW: '|| RAWTOHEX(message_tbl_OUT(item_count).Mraw); ELSE temp_varchar2 := 'Invalid item type: '|| TO_CHAR(next_item); RAISE invalid_item_type; END IF; /* || display results and get next item type [Appendix A] What's on the Companion Disk? 3.1.7 DBMS_PIPE Examples 172 */ IF display_TF THEN DBMS_OUTPUT.PUT_LINE(temp_varchar2); END IF; next_item := DBMS_PIPE.NEXT_ITEM_TYPE; END LOOP; EXCEPTION WHEN invalid_item_type THEN message_tbl_OUT := null_message_tbl; END unpack_to_tbl; PROCEDURE pack_from_tbl (message_tbl_IN IN message_tbltype) IS /* || packs the session message buffer from a generic || message table */ BEGIN FOR i IN message_tbl_IN.FIRST message_tbl_IN.LAST LOOP IF message_tbl_IN(i).item_type = 9 THEN DBMS_PIPE.PACK_MESSAGE(message_tbl_IN(i).Mvarchar2); ELSIF message_tbl_IN(i).item_type = 6 THEN DBMS_PIPE.PACK_MESSAGE(message_tbl_IN(i).Mnumber); ELSIF message_tbl_IN(i).item_type = 12 THEN DBMS_PIPE.PACK_MESSAGE(message_tbl_IN(i).Mdate); ELSIF message_tbl_IN(i).item_type = 11 THEN DBMS_PIPE.PACK_MESSAGE_ROWID(message_tbl_IN(i).Mrowid); ELSIF message_tbl_IN(i).item_type = 23 THEN DBMS_PIPE.PACK_MESSAGE_RAW(message_tbl_IN(i).Mraw); END IF; END LOOP; ENDpack_from_tbl; I really like these utilities, but they suffer from a potentially serious limitation inherited from Oracle's rather poor memory management for PL/SQL tables of records. Basically, each row of a PL/SQL table of type message_tbltype consumes at least enough memory to fill out the variable−length columns, which is greater than eight kilobytes. Thus, unpacking a message with more than a few items in it can result in a very large PL/SQL table. This is demonstrated by the following test results, which use the my_session.memory procedure (see Chapter 11, Managing Session Information) to display user session memory before and after unpacking a message. /* Filename on companion disk: pipemem.sql. */* set serveroutput on size 100000 [Appendix A] What's on the Companion Disk? 3.1.7 DBMS_PIPE Examples 173 DECLARE null_msg_tbl dbpipe.message_tbltype; msg_tbl dbpipe.message_tbltype; call_stat INTEGER; BEGIN /* pack a message with a number of items */ FOR i in 1 50 LOOP DBMS_PIPE.PACK_MESSAGE('message number: '||TO_CHAR(i)); END LOOP; /* send and receive the message */ call_stat :=DBMS_PIPE.SEND_MESSAGE('PIPEX'); call_stat :=DBMS_PIPE.RECEIVE_MESSAGE('PIPEX'); /* use the generic unpack and show memory */ dbpipe.unpack_to_tbl(msg_tbl,FALSE); my_session.memory; /* now free, release and show memory */ msg_tbl := null_msg_tbl; DBMS_SESSION.FREE_UNUSED_USER_MEMORY; my_session.memory; END; / session UGA: 41160 session PGA: 987576 session UGA: 41160 session PGA: 137760 PL/SQL procedure successfully completed. The test shows that using unpack_to_tbl on a message with 50 items results in session PGA memory exceeding 900 kilobytes in size, most of which is wasted. Clearly, this is not a good scenario for a real application with many users, so the general usefulness of unpack_to_tbl and pack_from_tbl will have to wait until Oracle fixes these PL/SQL memory management problems. NOTE: The problem caused by unpacking messages with more than a few items in them can result in a very large PL/SQL table that has been fixed in Oracle PL/SQL8. 3.1.7.3.2 The peek procedure Developers or DBAs working with and testing DBMS_PIPE applications may really like the peek procedure built on top of the generic pack and unpack procedures. The peek procedure lets you pull a message off any pipe (which you have permission to use), look at its content, and place it back into the pipe, if you desire. Note that using peek will change the message order in the pipe, since database pipes are FIFO queues. /* Filename on companion disk: dbpipe.sql */* PROCEDURE peek (pipename_IN IN VARCHAR2 ,timeout_secs_IN IN INTEGER := 60 ,replace_message_TF IN BOOLEAN := TRUE) IS /* || Takes a sample message from a pipe, unpacks and displays || contents using unpack_to_tbl procedure. || || If replace_message_TF parameter is TRUE (the default), || then the message is replaced into the pipe.NOTE: this || will change message order in the pipe. [Appendix A] What's on the Companion Disk? 3.1.7 DBMS_PIPE Examples 174 */ message_tblmessage_tbltype; call_statusINTEGER; /* empty table used to free and release memory */ null_message_tblmessage_tbltype; BEGIN call_status := DBMS_PIPE.RECEIVE_MESSAGE (pipename=>pipename_IN, timeout=>timeout_secs_IN); IF call_status = 0 THEN unpack_to_tbl(message_tbl, display_TF=>TRUE); IF replace_message_TF THEN /* || repack message into initialized buffer */ DBMS_PIPE.RESET_BUFFER; pack_from_tbl(message_tbl); /* || replace message on the pipe */ call_status := DBMS_PIPE.SEND_MESSAGE (pipename=>pipename_IN, timeout=>0); END IF; /* || empty message_tbl and free memory */ message_tbl := null_message_tbl; DBMS_SESSION.FREE_UNUSED_USER_MEMORY; END IF; END peek; The peek procedure takes the memory management limitations into account. It returns memory consumed by the unpack_to_tbl procedure to the operating system by initializing message_tbl and calling DBMS_SESSION.FREE_UNUSED_USER_MEMORY. 3.1.7.3.3 The forward procedure The final fun utility from dbpipe to be discussed here is the forward procedure, which lets you forward a message from one pipe to another. The procedure has four IN parameters: from_pipename_IN and to_pipename_IN Receiving and sending pipes for the message forwarding. timeout_secs_IN Determines the number of seconds to wait for a message to forward (on the pipe from_pipename_IN). safe_mode_IN A Boolean that determines which of two message forwarding techniques to use (which I call "safe" and "cool"). Safe mode forwarding uses unpack_to_tbl and pack_from_tbl to physically unbundle and recreate the message before sending it on to_pipename_IN. Cool mode forwarding is based on the idea that the best way to forward a message should be to execute [Appendix A] What's on the Companion Disk? 3.1.7 DBMS_PIPE Examples 175 . message buffer in index order. The unpack_to_tbl procedure can also optionally use the DBMS_OUTPUT built−in package (described in Chapter 6, Generating Output from PL/SQL Programs) to display the. really like these utilities, but they suffer from a potentially serious limitation inherited from Oracle& apos;s rather poor memory management for PL/SQL tables of records. Basically, each row of. many users, so the general usefulness of unpack_to_tbl and pack_from_tbl will have to wait until Oracle fixes these PL/SQL memory management problems. NOTE: The problem caused by unpacking messages

Ngày đăng: 07/07/2014, 00:20

TỪ KHÓA LIÊN QUAN