Как включить массив (или аналогичный) в оператор SQL в предложении? - PullRequest
0 голосов
/ 13 июня 2019

Я новичок в Oracle и PL SQL. В настоящее время я борюсь с обработкой массивов и "подобными вещами", такими как коллекция. Я пытаюсь построить процедуру как:

procedure insert_by_array( my_array some_array_type)
begin

insert into table1 (some_column)
select some_column 
from table2
where column2 in my_array 
;

end;

Однако я не мог сделать, я попробовал некоторые типы массивов, но я не нашел правильный. Записи типа должны быть varchar2 - часть этого критерия Я открыт для любого типа массива. Т.е. когда мой тип массива

type array_of_strings is varray(100) of varchar2(40);

Моя ошибка: «Типы локальных коллекций не допускаются в операторах SQL» Я использую Oracle Database 12c Enterprise Edition Release 12.1.0.2.0.

Итак, в конце это сработало:

create type table_of_strings IS TABLE OF VARCHAR2(64); --define it global;

declare
my_table table_of_strings;

begin
my_table := table_of_strings('aaa', 'bb','c');

insert into table1 (some_column)
select some_column 
from table2
where column2 in (select column_value from table(my_table))
;

end;

Ответы [ 2 ]

2 голосов
/ 13 июня 2019

Прежде всего, вы должны определить коллекцию уровня SQL. (Varray не вариант)

create type array_of_strings as table of varchar2(40);

Теперь вы можете использовать таблицу или «член» подхода

declare 
c array_of_strings := new array_of_strings();
begin
c.extend();
c(c.count) := 'A';
c.extend();
c(c.count) := 'B';

for rec in (select * from dual where 'A' member of c ) loop
  dbms_output.put_line('Option with memeber of ');
end loop;


for rec in (select * from dual where 'A' in (select * from table(c))) loop
  dbms_output.put_line('Option with table');
end loop;

end; 
0 голосов
/ 13 июня 2019

Как говорит ошибка, локальные коллекции, определенные в процедуре, функции, блоке кода, не могут использоваться в запросах, по крайней мере, в Oracle 11, который я использую.

Это не работает (PLS-00642):

declare 
  type strings is table of varchar2(5);
  v_i strings := strings('A', 'X', 'Q');
  v_o strings;
begin 
  select * bulk collect into v_o from dual where dummy in (select * from table(v_i));
end;

Итак ... либо используйте тип, определенный на уровне схемы (ваш собственный или предопределенный sys.odcivarchar2list):

declare 
  type strings is table of varchar2(5);
  v_i strings := strings('A', 'X', 'Q');
  v_o strings;
  v_so sys.odcivarchar2list := sys.odcivarchar2list();
begin 
  v_so.extend(v_i.count);
  for i in 1..v_i.count loop
    v_so(i) := v_i(i);
  end loop;
  select * bulk collect into v_o from dual where dummy in (select * from table(v_so));
end;

... либо использовать динамический sql:

declare 
  type strings is table of varchar2(5);
  v_i strings := strings('A', 'X', 'Q');
  v_o strings;
  v_str varchar2(4000);
begin 
  for i in 1..v_i.count loop
    v_str := v_str || case when i > 1 then ', ' end || ''''||v_i(i)||'''';
  end loop;
  execute immediate 'select * from dual where dummy in ('||v_str||')' bulk collect into v_o ;
end;

... либо используйте цикл (возможно, самый медленный):

declare 
  type strings is table of varchar2(5);
  v_i strings := strings('A', 'X', 'Q');
  v_o strings := strings();
begin 
  for rec in (select * from dual) loop
    if rec.dummy member of v_i then 
      v_o.extend();
      v_o(v_o.count) := rec.dummy;
    end if;
  end loop;
end;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...