2010-06-15 50 views
0

我有下面的oracle函数,但它不起作用和出错。我用Ask Tom's方式转换的select * from table1 where col1 in <>在oracle函数体中的逗号分隔值

使用封装头部声明逗号分隔值:

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) 

可以索姆请告诉我我在这里可能会做错什么?

+0

是什么。可您发布它,你得到错误。 – josephj1989 2010-06-16 00:55:52

回答

2

你不给我们实际的错误,这使我们很难诊断你的问题。然而,它值得一试:ORA-00902: invalid datatype

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

所以,从包中取出MyTableType的declration和SQL创建它....

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

您选择语句现在应该工作。如果没有,请编辑您的问题以给我们确切的错误信息。

编辑

“我想要的一切是 包内。我有什么改变来 实现这一目标?”

这是一个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()汤姆凯特的解决方案。 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 *工作加:

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> 
+0

我试图从包中删除MyTableType声明,并将它保存在SQL以外,并且工作正常。但我希望一切都在包装内。我需要做些什么才能做到这一点? – dmitry 2010-06-16 03:56:55

+0

查询只能使用“SQL”类型,而不能使用“PL/SQL”类型。 – 2010-06-16 04:23:51