PL/SQL:声明要在 IN 条件中使用的数字列表

and*_*riy 5 oracle plsql

是否可以定义将在光标选择中使用的 id 列表?

我尝试按照以下方式进行操作

DECLARE
  insert_user_id number := 1;
  type nt_type is table of number;
  building_num nt_type := nt_type (1,2,3,4,5);

cursor curs1 is
(
  select ID 
  from objects 
  where BUILDING_NUM in (building_num)
);
Run Code Online (Sandbox Code Playgroud)

但我得到的是以下错误:

PLS-00642: local collection types not allowed in SQL statements
Run Code Online (Sandbox Code Playgroud)

我发现,如果我以这种方式声明数字列表,就可以通过Loop它们。但我不想要它。我想要的只是在IN光标的条件内。

我该怎么做?

你想问我,为什么我不把 id 放在INin 游标中?我的答案是:我有几个使用相同列表 id 的游标。

编辑

根据下面的答案,代码如下:

create type nt_type is table of number;

DECLARE
  insert_user_id number := 1;
  building_num nt_type := nt_type (1,2,3,4,5);

cursor curs1(building_nums nt_type) is
(
  select ID 
  from objects 
  where BUILDING_NUM in (select * from table(building_nums))
); 
Run Code Online (Sandbox Code Playgroud)

use*_*735 2

根本问题是 SQL 查询在 SQL 上下文中运行,并且无法访问type nt_type is table of number;匿名 PL/SQL 块中定义的私有 PL/SQL 类型。相反,您必须使用 SQL 类型。下面您将找到如何将数字列表传递给光标的示例。我相信您可以根据您的问题调整这个想法!

create table so56_t (
 id number
,d varchar2(1)
);

insert into so56_t values(1, 'A');
insert into so56_t values(2, 'B');
insert into so56_t values(3, 'C');
insert into so56_t values(4, 'D');

-- SQL type required (PL/SQL type won't work)
create type num_list_t is table of number;
/

declare
  cursor cur_c(p_ids num_list_t) is
    select * from so56_t where id in (select* from table(p_ids));
begin
  declare
    v_foos constant num_list_t := num_list_t(1, 3);
    v_bars constant num_list_t := num_list_t(2, 4);

    v_r cur_c%rowtype;
  begin
    open cur_c(v_foos);
    loop
      fetch cur_c into v_r;
      exit when cur_c%notfound;
      dbms_output.put_line(v_r.d);
    end loop;
    close cur_c;

    open cur_c(v_bars);
    loop
      fetch cur_c into v_r;
      exit when cur_c%notfound;
      dbms_output.put_line(v_r.d);
    end loop;
    close cur_c;
  end;
end;
/
Run Code Online (Sandbox Code Playgroud)

运行示例

SQL> /
A
C
B
D

PL/SQL procedure successfully completed.

SQL>
Run Code Online (Sandbox Code Playgroud)