I have been recently asked to develop a pl/sql stored procedure in order to dequeue a payload message from an Oracle Advanced queue. It was a text message. Don’t ask me why they didn’t foresee an object type for that purpose, I did asked the same question and I have been told that this is the standard they have been successfully using since several years and they do not have the intention to change it.
The goal is to dequeue that text message and extract from it several fields that are separated by a given delimiter. I decided to reproduce this development in a blog article so that I can found it easily and also redirect to it when similar request will be done in Oracle forums.
mhouri.world> create or replace package split_text 3 IS 4 TYPE t_msg_array IS TABLE OF VARCHAR2(4000) INDEX BY BINARY_INTEGER; 7 FUNCTION f_extract_message_info (piv_message IN VARCHAR2 8 ,piv_delim IN VARCHAR2) 9 RETURN t_msg_array; 11 END split_text; 12 / Package created.
mhouri.world> create or replace package body split_text 2 IS 3 FUNCTION f_extract_message_info (piv_message IN VARCHAR2 5 ,piv_delim IN VARCHAR2) 6 RETURN t_msg_array 7 IS 8 l_t_msg_array t_msg_array; 9 ln_pos NUMBER := 0; 10 li INTEGER := 0; 11 lv_str VARCHAR2 (4000) := piv_message; 12 13 BEGIN 14 -- Get the position fo the first delimitor 15 ln_pos := instr(lv_str,piv_delim,1,1); 16 17 -- While there is still delimitors loop 18 WHILE ( ln_pos != 0) 19 LOOP 20 21 -- Remove the first delimitor from the message 22 lv_str := substr(lv_str,ln_pos + length(piv_delim),length(lv_str)); 23 24 -- Determine now the new position of the first delimiter 25 ln_pos := instr(lv_str,piv_delim,1,1); 26 27 -- Fill each information of the message in an array 28 li := li + 1; 29 IF ln_pos != 0 30 THEN 31 l_t_msg_array(li) := substr(lv_str,1, ln_pos-1); 32 ELSE 33 l_t_msg_array(li) := lv_str; 34 END IF; 35 36 END LOOP; 37 38 -- return the array 39 RETURN l_t_msg_array; 41 END f_extract_message_info; 44 END split_text; 45 / Package body created.
Few points should be taken into account
- piv_delim represents the fields delimiter
- the message text should starts by the delimiter
mhouri.world> set serveroutput on
mhouri.world> declare
2 piv_txt varchar2(4000);
3 l_t_jus_msg_array split_text.t_msg_array;
4
5 BEGIN
6
7 piv_txt := '#@test01#@test02#@test03';
8
9 l_t_jus_msg_array := split_text.f_extract_message_info(piv_txt,'#@');
10
11 dbms_output.put_line(' item1 := '||l_t_jus_msg_array(1) );
12 dbms_output.put_line(' item2 := '||l_t_jus_msg_array(2));
13 dbms_output.put_line(' item3 := '||l_t_jus_msg_array(3));
14
15
16 END;
17 /
item1 := test01
item2 := test02
item3 := test03
PL/SQL procedure successfully completed.