Jim*_*mmy 22 oracle plsql tokenize
我有CSV字符串100.01,200.02,300.03,我需要传递给Oracle中的PL/SQL存储过程.在proc中,我需要在表格的Number列中插入这些值.
为此,我从这里得到了一个工作方法:
[2]按级别使用SQL连接.
现在,我有另一个要求.我需要传递2个CSV字符串[长度相等]作为PL/SQL存储过程的输入.我需要打破这个字符串并将两个CSV字符串中的每个值插入表格中的两个不同列.请你让我知道怎么去吗?
CSV输入示例:mystring varchar2(2000):='0.75,0.64,0.56,0.45';
myAmount varchar2(2000):='0.25,0.5,0.65,0.8';
myString值将进入A列,myAmount值进入表中的B列.
你能告诉我如何实现这个目标吗?
谢谢.
这是一个很好的解决方案:
FUNCTION comma_to_table(iv_raw IN VARCHAR2) RETURN dbms_utility.lname_array IS
ltab_lname dbms_utility.lname_array;
ln_len BINARY_INTEGER;
BEGIN
dbms_utility.comma_to_table(list => iv_raw
,tablen => ln_len
,tab => ltab_lname);
FOR i IN 1 .. ln_len LOOP
dbms_output.put_line('element ' || i || ' is ' || ltab_lname(i));
END LOOP;
RETURN ltab_lname;
END;
Run Code Online (Sandbox Code Playgroud)
来源:CSV - 逗号分隔值 - 和PL/SQL(链接不再有效)
这应该做你想要的..它假设你的列表将永远只是数字.如果不是这种情况,只需将对DBMS_SQL.NUMBER_TABLE的引用更改为适用于所有数据的表类型:
CREATE OR REPLACE PROCEDURE insert_from_lists(
list1_in IN VARCHAR2,
list2_in IN VARCHAR2,
delimiter_in IN VARCHAR2 := ','
)
IS
v_tbl1 DBMS_SQL.NUMBER_TABLE;
v_tbl2 DBMS_SQL.NUMBER_TABLE;
FUNCTION list_to_tbl
(
list_in IN VARCHAR2
)
RETURN DBMS_SQL.NUMBER_TABLE
IS
v_retval DBMS_SQL.NUMBER_TABLE;
BEGIN
IF list_in is not null
THEN
/*
|| Use lengths loop through the list the correct amount of times,
|| and substr to get only the correct item for that row
*/
FOR i in 1 .. length(list_in)-length(replace(list_in,delimiter_in,''))+1
LOOP
/*
|| Set the row = next item in the list
*/
v_retval(i) :=
substr (
delimiter_in||list_in||delimiter_in,
instr(delimiter_in||list_in||delimiter_in, delimiter_in, 1, i ) + 1,
instr (delimiter_in||list_in||delimiter_in, delimiter_in, 1, i+1) - instr (delimiter_in||list_in||delimiter_in, delimiter_in, 1, i) -1
);
END LOOP;
END IF;
RETURN v_retval;
END list_to_tbl;
BEGIN
-- Put lists into collections
v_tbl1 := list_to_tbl(list1_in);
v_tbl2 := list_to_tbl(list2_in);
IF v_tbl1.COUNT <> v_tbl2.COUNT
THEN
raise_application_error(num => -20001, msg => 'Length of lists do not match');
END IF;
-- Bulk insert from collections
FORALL i IN INDICES OF v_tbl1
insert into tmp (a, b)
values (v_tbl1(i), v_tbl2(i));
END insert_from_lists;
Run Code Online (Sandbox Code Playgroud)
我使用apex_util.string_to_table来解析字符串,但如果您愿意,可以使用不同的解析器.然后您可以插入数据,如下例所示:
declare
myString varchar2(2000) :='0.75, 0.64, 0.56, 0.45';
myAmount varchar2(2000) :='0.25, 0.5, 0.65, 0.8';
v_array1 apex_application_global.vc_arr2;
v_array2 apex_application_global.vc_arr2;
begin
v_array1 := apex_util.string_to_table(myString, ', ');
v_array2 := apex_util.string_to_table(myAmount, ', ');
forall i in 1..v_array1.count
insert into mytable (a, b) values (v_array1(i), v_array2(i));
end;
Run Code Online (Sandbox Code Playgroud)
Apex_util可从Oracle 10G开始提供.在此之前,它被称为htmldb_util,默认情况下未安装.如果你不能使用它,你可以使用我多年前写的字符串解析器并发布在这里.