【问题标题】: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

【问题讨论】:

    标签: oracle if-statement stored-procedures plsql


    【解决方案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 (...) 语句替换整个循环。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-05-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多