Does Pl/SQL Have an Equivalent Stringtokenizer to Java'S

How to use a comma-separated list of strings as pl/sql stored function parameter inside a NOT IN clause of a select statement

Here's my solution using dynamic sql for my original question above:

CREATE TABLE example ( somevalue VARCHAR(36) NOT NULL);
--
INSERT INTO example VALUES ('value1');
INSERT INTO example VALUES ('value2');
INSERT INTO example VALUES ('value3');
--
SELECT * FROM example;
--
CREATE OR REPLACE
FUNCTION resultmaker(
ignoreList IN VARCHAR2)
RETURN VARCHAR2
IS
result VARCHAR2(4000);
example_cursor sys_refcursor;
rec example.somevalue%type;
BEGIN
result := 'Here is my calculated result, using ignorelist=' || ignoreList || ':' || CHR(10);
OPEN example_cursor FOR ( 'SELECT DISTINCT somevalue FROM example WHERE somevalue NOT IN (' || ignoreList || ')' );
FETCH example_cursor INTO rec;
WHILE example_cursor%found
LOOP
result := result || 'not in ignorelist: ' || rec || CHR(10);
FETCH example_cursor INTO rec;
END LOOP;
CLOSE example_cursor;
result := result || '.' || CHR(10);
--
RETURN result;
END resultmaker;
/
--
-- simulate function call with user input 'value2', 'value3'
SELECT resultmaker('''value2'', ''value3''') FROM dual;
--
DROP TABLE example;
DROP FUNCTION resultmaker;

Does Oracle provide the way of returning multiple substrings from a string/clob row that has been parsed?

Something like this maybe:

CREATE OR REPLACE FUNCTION explode(longline varchar)
RETURN sys.dbms_debug_vc2coll PIPELINED
IS
pos PLS_INTEGER;
lastpos PLS_INTEGER;
element varchar(2000);
BEGIN
lastpos := 1;
pos := instr(longline, ',');

while pos > 0 loop
element := substr(longline, lastpos, pos - lastpos);
lastpos := pos + 1;
pos := instr(longline, ',', lastpos);
pipe row(element);
end loop;

if lastpos <= length(longline) then
pipe row (substr(longline, lastpos));
end if;

RETURN;
END;
/

This can be used like this:


SQL> select * from table(explode('1,2,3'));

COLUMN_VALUE
---------------------------------------------
1
2
3
SQL>

If you are not on 11.x you need to define the return type yourself:

create type char_table as table of varchar(4000);

and change the function declaration to:

CREATE OR REPLACE FUNCTION explode(longline varchar)
RETURN char_table pipelined
.....

insert multiple select value in one column using Mysql and Java

For those who want to do the same thing as me, do research more on String tokenizer in sql. Does PL/SQL have an equivalent StringTokenizer to Java's?

StringTokenizer not working properly with delim //

StringTokenizer takes both the tokens as separate, and tokenizes on both of them. So, it is tokenizing on both // and /, and hence the result.


I would rather prefer String#split over StringTokenizer. It's easier to use, and has more options. It can take Regex as parameter, and returns an array of tokens which you can use later on: -

String  mStr = "abcd//aaa//32434//3/34343";

String[] arr = mStr.split("//");
System.out.println(Arrays.toString(arr));

Output : -

[abcd, aaa, 32434, 3/34343]

Split String by delimiter position using oracle SQL

You want to use regexp_substr() for this. This should work for your example:

select regexp_substr(val, '[^/]+/[^/]+', 1, 1) as part1,
regexp_substr(val, '[^/]+$', 1, 1) as part2
from (select 'F/P/O' as val from dual) t

Here, by the way, is the SQL Fiddle.

Oops. I missed the part of the question where it says the last delimiter. For that, we can use regex_replace() for the first part:

select regexp_replace(val, '/[^/]+$', '', 1, 1) as part1,
regexp_substr(val, '[^/]+$', 1, 1) as part2
from (select 'F/P/O' as val from dual) t

And here is this corresponding SQL Fiddle.

Is there a function to split a string in Oracle PL/SQL?

You have to roll your own. E.g.,

/* from :http://www.builderau.com.au/architect/database/soa/Create-functions-to-join-and-split-strings-in-Oracle/0,339024547,339129882,00.htm

select split('foo,bar,zoo') from dual;
select * from table(split('foo,bar,zoo'));

pipelined function is SQL only (no PL/SQL !)
*/

create or replace type split_tbl as table of varchar2(32767);
/
show errors

create or replace function split
(
p_list varchar2,
p_del varchar2 := ','
) return split_tbl pipelined
is
l_idx pls_integer;
l_list varchar2(32767) := p_list;
l_value varchar2(32767);
begin
loop
l_idx := instr(l_list,p_del);
if l_idx > 0 then
pipe row(substr(l_list,1,l_idx-1));
l_list := substr(l_list,l_idx+length(p_del));

else
pipe row(l_list);
exit;
end if;
end loop;
return;
end split;
/
show errors;

/* An own implementation. */

create or replace function split2(
list in varchar2,
delimiter in varchar2 default ','
) return split_tbl as
splitted split_tbl := split_tbl();
i pls_integer := 0;
list_ varchar2(32767) := list;
begin
loop
i := instr(list_, delimiter);
if i > 0 then
splitted.extend(1);
splitted(splitted.last) := substr(list_, 1, i - 1);
list_ := substr(list_, i + length(delimiter));
else
splitted.extend(1);
splitted(splitted.last) := list_;
return splitted;
end if;
end loop;
end;
/
show errors

declare
got split_tbl;

procedure print(tbl in split_tbl) as
begin
for i in tbl.first .. tbl.last loop
dbms_output.put_line(i || ' = ' || tbl(i));
end loop;
end;

begin
got := split2('foo,bar,zoo');
print(got);
print(split2('1 2 3 4 5', ' '));
end;
/


Related Topics



Leave a reply



Submit