Code Listing 2:
string_fun Package with full BETWNSTR implementation
ALTER SESSION SET plsql_ccflags = 'max_varchar2_length:32767'
/
CREATE OR REPLACE PACKAGE string_fun
IS
SUBTYPE maxvarchar2_t IS VARCHAR2 ( $$max_varchar2_length );
TYPE maxvarchar2_aat IS TABLE OF maxvarchar2_t
INDEX BY PLS_INTEGER;
TYPE clob_aat IS TABLE OF CLOB
INDEX BY PLS_INTEGER;
FUNCTION betwnstr (
string_in IN VARCHAR2
, start_in IN PLS_INTEGER
, end_in IN PLS_INTEGER
, inclusive_in IN BOOLEAN := TRUE
)
RETURN VARCHAR2;
FUNCTION list_to_collection (
string_in IN VARCHAR2
, delim_in IN VARCHAR2 DEFAULT ','
)
RETURN maxvarchar2_aat;
FUNCTION cloblist_to_collection (
string_in IN CLOB
, delim_in IN VARCHAR2 DEFAULT ','
)
RETURN clob_aat;
END string_fun;
/
CREATE OR REPLACE PACKAGE BODY string_fun
IS
FUNCTION betwnstr (
string_in IN VARCHAR2
, start_in IN PLS_INTEGER
, end_in IN PLS_INTEGER
, inclusive_in IN BOOLEAN := TRUE
)
RETURN VARCHAR2
IS
c_last CONSTANT PLS_INTEGER := LENGTH ( string_in );
l_start PLS_INTEGER;
l_numchars PLS_INTEGER
:= LEAST ( ABS ( end_in ), c_last ) - ABS ( start_in )
+ 1;
BEGIN
IF string_in IS NULL
OR ( start_in < 0 AND end_in > 0 )
OR ( start_in > 0 AND end_in < 0 )
OR ( start_in < 0 AND end_in > start_in )
OR ( start_in > 0 AND end_in < start_in )
THEN
RETURN NULL;
ELSE
IF start_in < 0
THEN
l_start := GREATEST ( end_in, -1 * LENGTH ( string_in ));
ELSIF start_in = 0
THEN
l_start := 1;
l_numchars := ABS ( end_in ) - ABS ( l_start ) + 1;
ELSE
l_start := start_in;
END IF;
IF NOT NVL ( inclusive_in, FALSE )
THEN
l_start := l_start + 1;
l_numchars := l_numchars - 2;
END IF;
RETURN ( SUBSTR ( string_in, l_start, l_numchars ));
END IF;
END betwnstr;
FUNCTION cloblist_to_collection (
string_in IN CLOB
, delim_in IN VARCHAR2 DEFAULT ','
)
RETURN clob_aat
IS
l_loc PLS_INTEGER;
l_row PLS_INTEGER := 1;
l_startloc PLS_INTEGER := 1;
l_return clob_aat;
BEGIN
IF string_in IS NOT NULL
THEN
LOOP
-- Get the next item.
l_loc := INSTR ( string_in, delim_in, l_startloc );
IF l_loc = l_startloc
THEN
l_return ( l_row ) := NULL;
ELSIF l_loc = 0
THEN
l_return ( l_row ) := SUBSTR ( string_in, l_startloc );
ELSE
l_return ( l_row ) :=
SUBSTR ( string_in, l_startloc, l_loc - l_startloc );
END IF;
-- Was that the last one?
IF l_loc = 0
THEN
EXIT;
ELSE
l_startloc := l_loc + 1;
l_row := l_row + 1;
END IF;
END LOOP;
END IF;
RETURN l_return;
END cloblist_to_collection;
FUNCTION list_to_collection (
string_in IN VARCHAR2
, delim_in IN VARCHAR2 DEFAULT ','
)
RETURN maxvarchar2_aat
IS
l_loc PLS_INTEGER;
l_row PLS_INTEGER := 1;
l_startloc PLS_INTEGER := 1;
l_return maxvarchar2_aat;
BEGIN
IF string_in IS NOT NULL
THEN
LOOP
-- Get the next item.
l_loc := INSTR ( string_in, delim_in, l_startloc );
IF l_loc = l_startloc
THEN
l_return ( l_row ) := NULL;
ELSIF l_loc = 0
THEN
l_return ( l_row ) := SUBSTR ( string_in, l_startloc );
ELSE
l_return ( l_row ) :=
SUBSTR ( string_in, l_startloc, l_loc - l_startloc );
END IF;
-- Was that the last one?
IF l_loc = 0
THEN
EXIT;
ELSE
l_startloc := l_loc + 1;
l_row := l_row + 1;
END IF;
END LOOP;
END IF;
RETURN l_return;
END list_to_collection;
END string_fun;
/
|