如何将数组(或类似内容)包含在子句中的SQL语句中?

时间:2019-06-13 08:12:22

标签: sql arrays oracle

我是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-此条件的一部分,我可以使用任何数组类型。即当我的array_type为

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

我的错误是:“ SQL语句中不允许使用本地集合类型” 我正在使用Oracle Database 12c企业版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 个答案:

答案 0 :(得分:2)

首先,您必须定义sql级别集合。 (不可使用varray)

[dynamictext dynamicname “CF7_get_post_var key=’title'”]

现在您可以使用表格或“成员”方法

create type array_of_strings as table of varchar2(40);

答案 1 :(得分:0)

正如错误所述,在过程,函数,代码块中定义的本地集合不能在查询中使用,至少在我使用的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;