我在pl / sql中编写了一个自定义函数,它根据提供的分隔符将clob变量拆分为一组字符串,但它没有按预期工作,请帮我解决代码问题。
create or replace
FUNCTION SPLITCLOB (p_in_string clob, p_delim VARCHAR2) RETURN t_array
IS
i number :=0;
pos number :=0;
lv_str clob := p_in_string;
Strings t_array:=t_array ();
Begin
-- determine first chuck of string
pos := DBMS_LOB.INSTR(lv_str,p_delim,1,1);
If ( pos = 0) Then
i := i + 1;
strings.Extend();
strings(i) := DBMS_LOB.SUBSTR(lv_str,1);
RETURN strings;
End If;
-- while there are chunks left, loop
WHILE ( pos != 0) LOOP
-- increment counter
i := i + 1;
-- create array element for chuck of string
strings.EXTEND();
strings(i) := DBMS_LOB.SUBSTR(lv_str,1,pos-1);
-- remove chunk from string
lv_str := DBMS_LOB.SUBSTR(lv_str,pos+1,dbms_lob.getLength(lv_str));
-- determine next chunk
pos := DBMS_LOB.INSTR(lv_str,p_delim,1,1);
-- no last chunk, add to array
IF pos = 0 THEN
strings.extend();
strings(i+1) := lv_str;
END IF;
End Loop;
-- return array
RETURN strings;
End Splitclob;
此处t_array()
是自定义类型的定义,在
create or replace
TYPE "T_ARRAY"
AS TABLE OF VARCHAR2(500);
提前致谢
答案 0 :(得分:1)
我已经改变了很久以前写的一段代码,它似乎可以按你的意愿运行。注意:如果输入参数中只有一个项目,它也会起作用(我的意思是,当输入中没有分隔符的情况被覆盖时)。
CREATE OR REPLACE
TYPE T_ARRAY
AS TABLE OF VARCHAR2(500);
/
CREATE OR REPLACE FUNCTION splitclob (p_clob_in CLOB, p_delim VARCHAR2) RETURN t_array
AS
v_buffer VARCHAR2(500);
v_len NUMBER;
v_offset NUMBER := 1;
v_delim_pos NUMBER;
v_amount NUMBER;
v_result_array t_array := t_array();
BEGIN
IF p_clob_in IS NOT NULL THEN
v_len := dbms_lob.getlength(p_clob_in);
WHILE v_offset < v_len
LOOP
v_delim_pos := instr(p_clob_in, p_delim, v_offset);
IF v_delim_pos = 0 THEN
v_amount := v_len - v_offset + 1;
ELSE
v_amount := v_delim_pos - v_offset;
END IF;
dbms_lob.read(p_clob_in, v_amount, v_offset, v_buffer);
v_offset := v_offset + v_amount + 1;
v_result_array.EXTEND;
v_result_array(v_result_array.LAST) := v_buffer;
END LOOP;
END IF;
RETURN v_result_array;
END;
/
DECLARE
v_array t_array;
BEGIN
v_array := splitclob('order_id=383325; order_line_item=59; order_class_id=5749; subscription_code=5U12PFNCAU; start_date=01/12/2012; end_date=30/11/2013; date_override=null; license_available=-1; license_consumed=1; license_override=-1; order_class_status=0', ';');
FOR v_i IN v_array.first..v_array.last
LOOP
dbms_output.put_line(v_i || ' ' || v_array(v_i));
END LOOP;
END;
/
输出:
1 order_id=383325 2 order_line_item=59 3 order_class_id=5749 4 subscription_code=5U12PFNCAU 5 start_date=01/12/2012 6 end_date=30/11/2013 7 date_override=null 8 license_available=-1 9 license_consumed=1 10 license_override=-1 11 order_class_status=0
当其中一个令牌超过500个字符时,您必须考虑这种情况。请记住,SQL上下文中的VARCHAR2
数据类型具有4000字节的限制。如果你知道不会有比这更长的令牌,那么你不必改变任何东西。