【问题标题】:IF ELSE statement inside another IF ELSE另一个 IF ELSE 中的 IF ELSE 语句
【发布时间】:2017-11-26 05:31:45
【问题描述】:

我的部分程序是这样的:

     declare 
         v_cnt_1  number;
         v_cnt_2 number;
    begin
        with input1  as(
        select .........
        from...
        where.....)
        select count(*) into v_cnt_1  
        from input1  t
        where......);

        with input2  as(
        select .........
        from...
        where.....)
        select count(*) into v_cnt_2 
        from input2  t
        where......);

       IF v_cnt_1 >0 or v_cnt_2 >0
      THEN DBMS_OUTPUT.PUT_LINE('all set');
      ELSE  DBMS_OUTPUT.PUT_LINE('take further action');
       end if;
       end;

我的目标是:如果此查询返回“采取进一步行动”的结果,那么我必须实施其他步骤,如果有进一步的 if/else 语句。如果返回“采取进一步行动”,我还有四种情况(if/else)要添加。如何在此输出的基础上添加 if/else?还是我需要创建另一个过程并在新过程中调用这个过程?

【问题讨论】:

    标签: sql oracle if-statement stored-procedures plsql


    【解决方案1】:

    "如果这个查询返回'采取进一步行动'的结果,那么我必须执行其他步骤,如果进一步的 if/else 语句。"

    我们可以嵌套 IF 语句。你没有说你的进一步陈述是什么,但你的代码可能看起来像这样:

    ...
    IF v_cnt_1 >0 or v_cnt_2 >0
        THEN DBMS_OUTPUT.PUT_LINE('all set');
    ELSE  
        --  take further action
        if whatever = 0  then
            DBMS_OUTPUT.PUT_LINE('do something #1');
        elsif whatever > 0 and yeahyeah = 0 then
            DBMS_OUTPUT.PUT_LINE('do something #2');
        elsif whatever > 0 and yeahyeah > 0 then
            DBMS_OUTPUT.PUT_LINE('do something #3');
       end if;
    end if;
    

    如果这是您需要的,您也可以将其构建为 CASE 语句:

    case
       when v_cnt_1 >0 or v_cnt_2 >0 then
            DBMS_OUTPUT.PUT_LINE('all set');
       when whatever = 0  then
            DBMS_OUTPUT.PUT_LINE('do something #1');
       when whatever > 0 and yeahyeah = 0 then
            DBMS_OUTPUT.PUT_LINE('do something #2');
       when whatever > 0 and yeahyeah > 0 then
            DBMS_OUTPUT.PUT_LINE('do something #3');
       else
            DBMS_OUTPUT.PUT_LINE('Unexpected state');
       end case;
    

    请注意,CASE 和 ID/ELSIF 评估会短路。这意味着程序首先执行第一个匹配条件,因此我们需要在一般情况之前有特定情况。这不好:

     case 
         when whatever = 0  and yeahyeah > 0 then
             dbms_output.put_line('do something');
         when whatever = 0 and yeahyeah = 1 then
             dbms_output.put_line('will never execute');
    

    “我需要创建另一个过程并在新过程中调用这个过程吗”

    不确定您的问题是什么,但如果执行的步骤很复杂(比如多于几行代码),调用程序会更干净——它们可以是本地的——因为它更容易阅读整个程序。在看起来像这样的骨架代码中:

    declare
        v_cnt_1  number;
        v_cnt_2 number;
        ...
        procedure proc1(p1 number) is 
        ...
        end p1;
    
        procedure proc2(p1 number) is 
        ...
        end p2;
    begin
        ...
        case
        when v_cnt_1 >0 or v_cnt_2 >0 then
            null -- 'all set';
       when whatever = 0  then
            proc1(v_cnt_1);
       when whatever > 0 and yeahyeah = 0 then
            proc1(v_cnt_2);
       when whatever > 0 and yeahyeah > 0 then
            proc1(v_cnt_1);
            proc2(v_cnt_2);
       else
           proc3(42);
       end case;
    

    这样很容易理解整个 case 语句并查看哪个条件触发了哪个操作。当然,给过程起有意义的名字有助于理解(Oracle 命名限制为 30 个字符,这并不总是容易的)。

    【讨论】:

      【解决方案2】:
          declare 
                   v_cnt_1  number;
                   v_cnt_2 number;
                   Take_further_action  boolean:=False;
              begin
                  with input1  as(
                  select .........
                  from...
                  where.....)
                  select count(*) into v_cnt_1  
                  from input1  t
                  where......);
      
                  with input2  as(
                  select .........
                  from...
                  where.....)
                  select count(*) into v_cnt_2 
                  from input2  t
                  where......);
      
                 IF v_cnt_1 >0 or v_cnt_2 >0
                THEN DBMS_OUTPUT.PUT_LINE('all set');
                ELSE  Take_futher_action :=True;
                       v_cnt_1 :=0;
                       v_cnt_2 :=0;
          --DBMS_OUTPUT.PUT_LINE('take further action');
                 end if;
          --Now put your select into statments here
          IF (v_cnt_1 >0 or v_cnt_2 >0) and Take_further_action  
                THEN DBMS_OUTPUT.PUT_LINE('all set');
      Take_further_action  :=False;
                ELSE  Take_further_action  :=True;
                       v_cnt_1 :=0;
                       v_cnt_2 :=0;
          --DBMS_OUTPUT.PUT_LINE('take further action');
                 end if;
      
          --Now again put your select into statments here
          IF (v_cnt_1 >0 or v_cnt_2 >0) and Take_further_action  
                THEN DBMS_OUTPUT.PUT_LINE('all set');
      Take_further_action  :=False;
                ELSE  Take_further_action  :=True;
                       v_cnt_1 :=0;
                       v_cnt_2 :=0;
      
                 end if;
             --You can perform any number of check with if-then-else as per required
      
                 end;
      

      【讨论】:

      • 为什么我必须使用相同的语句两次:IF (v_cnt_1 >0 or v_cnt_2 >0) and Take_further_action THEN DBMS_OUTPUT.PUT_LINE('all set');??
      • 是的 KKl 只有 Take_further_action 可用于处理其他条件。但逻辑上也是正确的
      最近更新 更多