2010-06-15 48 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