是否可以定义将在光标选择中使用的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)
);
但我得到的是以下错误:
PLS-00642: local collection types not allowed in SQL statements
我发现,如果我以这种方式声明数字列表,就可以Loop
通过它们。但我不想要它。我想要的只是在光标的IN
条件内。
我该怎么做?
我想问我,为什么我不把IN
中的ID放在光标中?我的回答是:我有几个使用相同列表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))
);
答案 0 :(得分:3)
1)Sql只允许使用sql级别的集合。你必须创建它。
create type nt_type is table of number;
2)查询shoull看起来像
DECLARE
building_num nt_type := nt_type (1,2,3,4,5);
begin
for rec in (select 1 from dual where 1 member of building_num) loop
null;
end loop;
end ;
DECLARE
building_num nt_type := nt_type (1,2,3,4,5);
begin
for rec in (select 1 from dual where 1 in (select column_value from table(building_num)) loop
null;
end loop;
end ;
此外,您可以检查数据库中是否有现有的号码集合并使用它。select * from ALL_COLL_TYPES where coll_type = 'TABLE' and elem_type_name = 'NUMBER'
答案 1 :(得分:2)
根本问题是SQL查询在SQL上下文中运行,并且无法访问匿名PL / SQL块中定义的私有PL / SQL类型type nt_type is table of number;
。相反,你必须使用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;
/
运行示例
SQL> /
A
C
B
D
PL/SQL procedure successfully completed.
SQL>
答案 2 :(得分:0)
如果您想使用字符串而不是数字表
DECLARE
insert_user_id number := 1;
building_nums varchar2(100) := '1,2,3,4,5';
cursor curs1 is
(
select ID
from objects
where BUILDING_NUM in (
SELECT to_number(REGEXP_SUBSTR (building_nums , '[^,]+', 1, LEVEL))
FROM DUAL
CONNECT BY REGEXP_SUBSTR (building_nums , '[^,]+', 1, LEVEL) IS NOT NULL
)
);
@ArkadiuszŁukasiewicz的变化回答
DECLARE
insert_user_id NUMBER := 1;
-- type nt_type is table of number;
svar VARCHAR2 (100) := '1,2,3,4,5';
building_nums nt_type;
n NUMBER;
CURSOR curs1
IS
(SELECT object_ID
FROM all_objects
WHERE object_id IN (SELECT COLUMN_VALUE
FROM TABLE (building_nums)));
BEGIN
SELECT TO_NUMBER (REGEXP_SUBSTR (svar, '[^,]+', 1, LEVEL))
BULK COLLECT INTO building_nums
FROM DUAL
CONNECT BY REGEXP_SUBSTR (svar, '[^,]+', 1, LEVEL) IS NOT NULL;
OPEN curs1;
LOOP
FETCH curs1 INTO n;
EXIT WHEN curs1%NOTFOUND;
dbms_output.put_line (n);
END LOOP;
CLOSE curs1;
END;
答案 3 :(得分:0)
您可以使用以下查询,将'1,2,3,4,5'替换为必需的值列表或从表中获取。
SELECT REGEXP_SUBSTR(('1,2,3,4,5'),'[^,]+', 1, LEVEL) FROM DUAL CONNECT BY REGEXP_SUBSTR(('1,2,3,4,5'), '[^,]+', 1, LEVEL) IS NOT NULL;
答案 4 :(得分:0)
这与您已经拥有的类似,除了我没有声明游标。我只是想发布它,以免对某人有帮助。
如前所述,首先创建表类型(nt_type)即可根据需要使用它,而不会引发错误:
PLS-00642: local collection types not allowed in SQL statements
话虽如此,这是另一个工作示例...
GIVEN:一个名为OBJECTS的表,其中包含以下数据:
ID BUILDING_NUM
---- ------------
1000 1
2000 2
3000 3
4000 4
5000 5
6000 6
7000 7
8000 8
9000 9
...和一个名为nt_type的类型
create type nt_type is table of number;
下面的PLSQL遍历OBJECTS表中的ID,其中BUILDING_NUM与给定集合(例如1,2,3,4,5)中的任何ID匹配,并输出一些文本到屏幕上。当然,它可以做一些更有用的事情,例如调用过程或执行一些SQL。
set serveroutput ON
DECLARE
building_nums nt_type := nt_type (1,2,3,4,5);
BEGIN
for i in (
select * from objects
where BUILDING_NUM in (select column_value from table(building_nums))
) LOOP
dbms_output.put_line('--do something with ID: '||i.ID||', matching building_num: '||i.BUILDING_NUM||';');
END LOOP;
END;
/
输出:
--do something with ID: 1000, matching building_num: 1;
--do something with ID: 2000, matching building_num: 2;
--do something with ID: 3000, matching building_num: 3;
--do something with ID: 4000, matching building_num: 4;
--do something with ID: 5000, matching building_num: 5;
PL/SQL procedure successfully completed.