-------------------------------------------------------- -- Some generic functions and types to work with strings -------------------------------------------------------- -- create or replace package str -- is -- -- A record for tokenizing strings -- type token_info is record ( -- string varchar2(4000), -- The string we will be tokenizing -- length integer, -- The length of the string -- token_start integer, -- Start of last token -- separators varchar2(4000) -- Characters which can separate tokens -- ); -- -- Return the first token in a string, or null if there are -- -- no more tokens -- function first_token ( -- string_in IN varchar2, -- token_rec_in IN OUT NOCOPY token_info, -- separators_in IN varchar2 := ' ' -- ) return varchar2; -- -- Get the next token in the string, or null if there are -- -- no more tokens -- function next_token ( -- token_rec_in IN OUT NOCOPY token_info -- ) return varchar2; -- -- Determine if a string has more tokens to be returned -- function has_more_tokens ( -- token_rec_in IN OUT NOCOPY token_info -- ) return char; -- end str; -- / -- show errors -- create or replace package body str -- is -- function first_token ( -- string_in IN varchar2, -- token_rec_in IN OUT NOCOPY token_info, -- separators_IN IN varchar2 := ' ' -- ) return varchar2 -- is -- begin -- token_rec_in.string := string_in; -- token_rec_in.length := length(string_in); -- token_rec_in.token_start := 1; -- token_rec_in.separators := separators_in; -- return next_token(token_rec_in); -- end first_token; -- function next_token ( -- token_rec_in IN OUT NOCOPY token_info -- ) return varchar2 -- is -- v_token_start integer; -- begin -- -- Check for string end -- if token_rec_in.token_start > token_rec_in.length then -- return null; -- end if; -- -- Skip separators -- while instr(token_rec_in.separators, -- substr(token_rec_in.string, -- token_rec_in.token_start, 1)) <> 0 -- loop -- token_rec_in.token_start := token_rec_in.token_start + 1; -- if token_rec_in.token_start > token_rec_in.length then -- return null; -- end if; -- end loop; -- v_token_start := token_rec_in.token_start; -- -- Skip until the next separator -- while instr(token_rec_in.separators, -- substr(token_rec_in.string, -- token_rec_in.token_start, 1)) = 0 -- loop -- token_rec_in.token_start := token_rec_in.token_start + 1; -- if token_rec_in.token_start > token_rec_in.length then -- return substr(token_rec_in.string, v_token_start); -- end if; -- end loop; -- return substr(token_rec_in.string, v_token_start, -- token_rec_in.token_start - v_token_start); -- end next_token; -- function has_more_tokens ( -- token_rec_in IN OUT NOCOPY token_info -- ) return char -- is -- begin -- if token_rec_in.token_start > token_rec_in.length then -- return 'f'; -- else -- return 't'; -- end if; -- end has_more_tokens; -- end str; -- / -- show errors