定义数组:
CREATE OR REPLACE
TYPE Varchar2Varray IS VARRAY(100) of VARCHAR2(40);
/定义函数:
CREATE OR REPLACE FUNCTION f_strsplit (STRING VARCHAR2, substring VARCHAR2)
   RETURN varchar2varray
IS
   len       INTEGER        := LENGTH (substring);
   lastpos   INTEGER        := 1 - len;
   pos       INTEGER;
   num       INTEGER;
   i         INTEGER        := 1;
   ret       varchar2varray := varchar2varray (NULL);
   /**自定义split函数,将指定的字符串按指定的标志符分割成字符数组*/
BEGIN
   LOOP
      pos := INSTR (STRING, substring, lastpos + len);      IF pos > 0
      THEN                                                            --found
         num := pos - (lastpos + len);
      ELSE                                                         --not found
         num := LENGTH (STRING) + 1 - (lastpos + len);
      END IF;      IF i > ret.LAST
      THEN
         ret.EXTEND;
      END IF;      ret (i) := SUBSTR (STRING, lastpos + len, num);
      EXIT WHEN pos = 0;
      lastpos := pos;
      i := i + 1;
   END LOOP;   RETURN ret;
END;
/调试:
输入参数:'ABC$DEFGH$IJKLMN$OPQRST', '$'调试时说:ORA-00911: invalid character
继续执行,代码经过了loop - end loop里的代码,但将鼠标放到变量ret时提示:undeclared identifier 'ret',
这是怎么回事?但为什么用如下语句成功呢?
SELECT *
  FROM TABLE (CAST (f_strsplit ('ABC$DEFGH$IJKLMN$OPQRST', '$') AS varchar2varray ) )

解决方案 »

  1.   

    直接将varchar2varray类型的变量显示出来的话是有问题的,
    必须把他转换成为可查询的类型比如表类型比如你举的例子中的CAST()函数转换类型,然后使用TABLE()函数将这个变量的值转变成表类型 使得可以进行查询-PS
    实际上楼主的只需要使用TABLE()函数转换varray类型为表类型后就可以查询了
    SQL> select * from table(f_strsplit('ABC$DEFGH$IJKLMN$OPQRST','$'));COLUMN_VALUE
    ----------------------------------------
    ABC
    DEFGH
    IJKLMN
    OPQRST
      

  2.   

    哈哈,你的存储过程没有任何问题,我测试过的,至于为什么会出现你说的“代码经过了loop - end loop里的代码,但将鼠标放到变量ret时提示:undeclared identifier 'ret',”,其实很简单,你在调试执行之前,单独对齐recompile就可以了。
      

  3.   

    同意baojianjun(包子)的回复,
    后来我只好用如下的脚本来获取分割后的数据了:FOR cur_str IN
                (SELECT *
                   FROM TABLE
                           (CAST
                               (f_strsplit ('ABC$DEFGH$IJKLMN$OPQRST', '$') AS varchar2varray
                               )
                           ))
             LOOP
               DBMS_OUTPUT.put_line (cur_str.column_value);
               --其他操作.
             END LOOP;