0

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

提前致谢

4

1 回答 1

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 订阅代码=5U12PFNCAU
5 开始日期=01/12/2012
6 结束日期=30/11/2013
7 日期覆盖=空
8 license_available=-1
9 license_consumed=1
10 license_override=-1
11 order_class_status=0

您必须考虑其中一个令牌长度超过 500 个字符的情况。请记住,VARCHAR2SQL 上下文中的数据类型有 4000 字节的限制。如果您知道不会有比这更长的令牌,那么您无需更改任何内容。

于 2013-11-04T12:48:12.053 回答