значения через запятую в теле функции оракула - PullRequest
0 голосов
/ 16 июня 2010

У меня есть следующая функция оракула, но она не работает и выдает ошибки. Я использовал Спросите Тома способ преобразования значений через запятую, которые будут использоваться в 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 Ответ

2 голосов
/ 16 июня 2010

Вы не сообщаете нам фактическую ошибку, из-за которой нам сложнее диагностировать вашу проблему. Тем не менее, это стоит денег: ORA-00902: invalid datatype

Вы не реализовали решение Тома в точности так, как он его дал. В частности, он создал myTableType как тип SQL, тогда как вы объявили его в спецификации пакета. Это не тривиальная деталь: мы не можем использовать типы PL / SQL в инструкциях SQL. Отсюда и исключение.

Итак, удалите объявление MyTableType из пакета и создайте его в SQL ....

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

Ваша инструкция SELECT теперь должна работать. Если это не так, отредактируйте ваш вопрос, чтобы сообщить нам точное сообщение об ошибке.

редактировать

«Я хочу, чтобы все было внутри пакет. Что я должен изменить на выполнить это? "

Вот клуге. Как видите, 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 * 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>
...