oracle函数体中逗号分隔的值

时间:2010-06-15 23:45:27

标签: oracle plsql tokenize

我有跟随oracle功能,但它不起作用和错误。我使用Ask Tom's方式转换逗号分隔值,以便在select * from table1 where col1 in <>

中使用

在包头中声明:

TYPE myTableType IS table of varchar2 (255);

包体的一部分:

l_string        long default iv_value_with_comma_separated|| ',';
l_data          myTableType := myTableType();
n               NUMBER;

begin
  begin
LOOP
    EXIT when l_string is null;
    n := instr( l_string, ',' );
     l_data.extend;
     l_data(l_data.count) := ltrim( rtrim( substr( l_string, 1, n-1 ) ) );
     l_string := substr( l_string, n+1 );
END LOOP;
end;

OPEN my_cursor FOR
  select * from table_a where column_a in (select * from table (l_data));
CLOSE my_cursor
END;
上面的

失败但是当我删除

时它工作正常
select * from table (l_data)

有人可以告诉我这里可能做错了吗?

1 个答案:

答案 0 :(得分:2)

您没有向我们提供实际错误,这使我们难以诊断您的问题。但是,值得一试:ORA-00902: invalid datatype

你没有像他给出的那样完全实现Tom的解决方案。具体来说,他创建了myTableType作为SQL类型,而您已在包规范中声明它。这不是一个简单的细节:我们不能在SQL语句中使用PL / SQL类型。因此例外。

因此,从包中删除MyTableType的declration并在SQL中创建它....

create or replace type mytabletype as table of varchar2(255);
/

您现在应该使用SELECT语句。如果没有,请编辑您的问题,以便向我们提供确切的错误消息。

修改

  

“我希望一切都在里面   包。我需要改变什么呢?   完成那个?“

这是一个kluge。如您所见,PKG1在规范中声明了PL / SQL类型:

SQL> create or replace package pkg1 as
  2      TYPE myTableType IS table of varchar2 (255);
  3      function split (p_string  in    long )
  4          return          myTableType ;
  5      function get_resultset (p_tab in myTableType)
  6          return sys_refcursor;
  7      function get_resultset_for_str (p_string  in    long)
  8          return sys_refcursor;
  9  end pkg1;
 10  /

Package created.

SQL>

在包体中,您将识别SPLIT()作为Tom Kyte的解决方案。 GET_RESULTSET()遍历传递的集合并组装动态SQL语句。 GET_RESULTSET_FOR_STR()是一个辅助函数,可以调用其他函数。

SQL> create or replace package body pkg1 as
  2      function split (p_string   in     long )
  3      return          myTableType
  4      is
  5              l_string        long default p_string || ',';
  6              l_data          myTableType := myTableType();
  7              n               number;
  8          begin
  9            loop
 10                exit when l_string is null;
 11                n := instr( l_string, ',' );
 12               l_data.extend;
 13               l_data(l_data.count) :=
 14                       ltrim( rtrim( substr( l_string, 1, n-1 ) ) );
 15               l_string := substr( l_string, n+1 );
 16          end loop;
 17          return l_data;
 18      end split;
 19
 20      function get_resultset (p_tab in myTableType)
 21          return sys_refcursor
 22      is
 23          return_value sys_refcursor;
 24          stmt varchar2(32767);
 25          i pls_integer := 1;
 26      begin
 27          stmt := 'select '''||p_tab(1)||''' from dual';
 28          while i < p_tab.count()
 29          loop
 30              i := i+1;
 31              stmt := stmt||' union all select '''||p_tab(i)||''' from dual';
 32          end loop;
 33          open return_value for stmt;
 34          return return_value;
 35      end get_resultset;
 36
 37      function get_resultset_for_str (p_string  in    long)
 38          return sys_refcursor
 39      is
 40          l_tab myTableType;
 41          return_value sys_refcursor;
 42      begin
 43          l_tab := split(p_string);
 44          return_value :=  get_resultset (l_tab);
 45          return return_value;
 46      end get_resultset_for_str;
 47
 48  end pkg1;
 49  /

Package body created.

SQL>

这是在SQL * Plus中使用的:

SQL> var rc refcursor
SQL> exec :rc := pkg1.get_resultset_for_str('ABC,DEF,XYZ')

PL/SQL procedure successfully completed.

SQL> print rc

'AB
---
ABC
DEF
XYZ

SQL>