检查是不是存在 PLS-00405:在此上下文中不允许子查询
Posted
技术标签:
【中文标题】检查是不是存在 PLS-00405:在此上下文中不允许子查询【英文标题】:Check if Exists PLS-00405: subquery not allowed in this context检查是否存在 PLS-00405:在此上下文中不允许子查询 【发布时间】:2018-04-20 20:00:37 【问题描述】:我有光标从 TableA 中选择,然后 Fetch Loop 插入到 TableB 中。
我想检查 TableB 中是否已经存在该值。
如果存在,那么我想跳过插入。
create or replace
PROCEDURE DAILY_RPT (
v_start IN DATE,
v_end IN DATE)
IS
ao_out_no out_pair.out_no%type;
cursor get is
SELECT ao_out_no from tableA;
BEGIN
open get;
LOOP
fetch get into ao_out_no;
EXIT WHEN get%NOTFOUND;
if (ao_out_no = (select out_no from TableA where out_no = ao_out_no) THEN
--DO NOTHING
else
INSERT INTO TABLEB(OUT_NO) VALUES (ao_out_no);
end if;
END LOOP;
close get;
END;
我使用了IF CONDITION
,但是,我使用变量进入 if 条件并且我正在低于。
PLS-00405: subquery not allowed in this context
if (ao_out_no = (select out_no from TableA where out_no = ao_out_no) THEN
【问题讨论】:
【参考方案1】:您根本不需要游标或 PL/SQL:
INSERT INTO TABLEB(OUT_NO)
SELECT ao_out_no
FROM tableA ta
WHERE ... -- filtering rows
AND NOT EXISTS (SELECT * From TableB tb WHERE tb.OUT_NO = ta.ao_out_no);
【讨论】:
我必须使用PL/SQL,这只是PL/SQL代码的一部分。 @user206168 所以只需用你的 PL/SQL 过程包装它,但仍然不需要显式 CURSOR【参考方案2】:使用以下内容:
for i in (
select out_no from TableA where out_no
)
loop
if i.out_no = ao_out_no
then
-- DO NOTHING
else
...
或
创建一个名为x
的新变量,然后通过
select out_no into x from TableA where out_no = ao_out_no;
并检查 x
的返回值。
【讨论】:
我确定这是在正确的行上,但光标在where out_no
之后缺少某些内容。【参考方案3】:
使用正确的语法,它会是这样的:
create or replace procedure daily_rpt
( v_start in date
, v_end in date )
as
begin
for r in (
select ao_out_no, 0 as exists_check
from tablea
)
loop
select count(*) into exists_check
from tablea
where out_no = r.ao_out_no
and rownum = 1;
if r.exists_check > 0 then
--DO NOTHING
else
insert into tableb (out_no) values (r.ao_out_no);
end if;
end loop;
end;
但是,查询所有行然后对每一行进行额外的查找以确定是否要使用它是低效的,因为 SQL 可以为您做这种事情。所以版本 2 可能类似于:
create or replace procedure daily_rpt
( v_start in date
, v_end in date )
as
begin
for r in (
select ao_out_no
from tablea
where not exists
( select count(*)
from tablea
where out_no = r.ao_out_no
and rownum = 1 )
)
loop
insert into tableb (out_no) values (r.ao_out_no);
end loop;
end;
此时您可以用insert ... where not exists (...)
语句替换整个循环。
【讨论】:
以上是关于检查是不是存在 PLS-00405:在此上下文中不允许子查询的主要内容,如果未能解决你的问题,请参考以下文章