自定义拆分功能在pl / sql中不起作用

时间:2013-11-04 11:58:51

标签: oracle plsql

我在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);

提前致谢

1 个答案:

答案 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字节的限制。如果你知道不会有比这更长的令牌,那么你不必改变任何东西。