Oracle 检查PLS-00405是否存在:在此上下文中不允许子查询

Oracle 检查PLS-00405是否存在:在此上下文中不允许子查询,oracle,if-statement,stored-procedures,plsql,Oracle,If Statement,Stored Procedures,Plsql,我让它从TableA中选择游标,然后获取插入TableB的循环 我想检查表B中是否已经存在该值 如果它存在,那么我想跳过插入 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

我让它从TableA中选择游标,然后获取插入TableB的循环

我想检查表B中是否已经存在该值

如果它存在,那么我想跳过插入

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条件
,然而,我在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

您根本不需要游标或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);
使用以下命令:

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

的返回值,使用正确的语法,它将如下所示:

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;

在这一点上,您可以使用
插入替换整个循环。。。where not exists(…)
语句。

我必须使用PL/SQL,这只是PL/SQL代码的一部分。@user206168所以只需用PL/SQL过程包装它,但仍然不需要显式游标。我确信这是在正确的行上,但游标在
where out\u no
之后缺少一些内容。