我有以下代码块:
DECLARE
CURSOR c_cursor IS
SELECT *
FROM table_a;
FOR i IN c_cursor LOOP
IF i.id NOT IN (SELECT id FROM table_b WHERE ind_val='Y')
THEN
BEGIN
INSERT INTO val_table_err
VALUES (''ERROR:id''|| i.id,
1,
1,
NULL,
1,
i.type_cd);
END;
END IF;
END LOOP;
我收到错误PLS-00405: SUBQUERY NOT ALLOWED IN THIS CONTEXT
任何有助于解决此问题的帮助都将不胜感激。
答案 0 :(得分:2)
您无法在任何版本的Oracle中执行此类NOT IN
。
将NOT IN
子句放入游标定义通常是有意义的。假设NOT IN
而不是NOT EXISTS
是更有效的方法,这样的事情就可以了。
CURSOR c_cursor IS
SELECT *
FROM table_a a
WHERE a.id NOT IN (SELECT b.id
FROM table_b b
WHERE ind_val = 'Y');
如果你真的希望在循环中完成检查,你需要一个不同的结构。你可以做点什么
FOR i IN c_cursor
LOOP
SELECT COUNT(*)
INTO l_cnt
FROM table_b b
WHERE b.id = i.id
AND b.ind_val = 'Y';
IF( l_cnt = 0 )
THEN
<<do something>>
END IF;
END LOOP;
当然,这不会像在游标中过滤贷款一样有效或明确。
答案 1 :(得分:1)
这与您的Oracle版本无关,我在11g中遇到了相同的错误,因为您不能在IF语句中使用NOT IN和子查询。
这是我的测试用例:
create table table_a (idA number);
create table table_b (idB number);
insert into table_a values(1);
insert into table_a values(2);
insert into table_b values(1);
commit;
此匿名pl / sql块与您的错误相同:
DECLARE
i number;
CURSOR c_cursor IS
SELECT idA
FROM table_a;
begin
FOR i IN c_cursor LOOP
IF i NOT IN (SELECT idB FROM table_b)
THEN
dbms_output.put_line(i);
END IF;
END LOOP;
end;
/
尝试这样的事情:
DECLARE
CURSOR c_cursor IS
SELECT idA, idB
FROM table_a a left join table_b on idA=idB;
i c_cursor%rowtype;
begin
FOR i IN c_cursor LOOP
IF i.idB is null
THEN
dbms_output.put_line(i.idA);
END IF;
END LOOP;
end;
/
它的好处是让oracle选择连接算法,而不是自己做一个嵌套循环。