【问题标题】:How to check if cursor returns any records in oracle?如何检查游标是否返回oracle中的任何记录?
【发布时间】:2012-05-30 10:03:56
【问题描述】:

我有一个使用游标的以下存储过程。根据游标是否返回任何记录,我需要进行一些处理。

但我不确定如何检查游标是否返回任何记录。

CREATE OR REPLACE PROCEDURE SP_EMPLOYEE_LOOKUP_BY_EMP_ID
(
      IN_USER_ID IN NUMBER, 
      IN_EMPLOYEE_ID NUMBER,
      IN_HC_AS_ON_DATE VARCHAR2,
      emp_cursor OUT SYS_REFCURSOR
) 
IS 

 CURSOR employees IS 
    SELECT  * FROM EMPLOYEE e; 

BEGIN    

if(record exist ) then 

 FOR employee IN employees
  LOOP  

        // do something  

  END LOOP; 
else if employees is empty then 
     // do something else 

END;

【问题讨论】:

    标签: oracle database-cursor


    【解决方案1】:

    不打开游标就无法检查是否返回记录。
    (见here
    因此,您可以进行一些快速查询以查看是否有记录(例如使用计数),

    或者,你可以这样做:

    CREATE OR REPLACE PROCEDURE SP_EMPLOYEE_LOOKUP_BY_EMP_ID
    (
          IN_USER_ID IN NUMBER, 
          IN_EMPLOYEE_ID NUMBER,
          IN_HC_AS_ON_DATE VARCHAR2,
          emp_cursor OUT SYS_REFCURSOR
    ) 
    IS 
    
     is_found_rec boolean := false;    
    
     CURSOR employees IS 
        SELECT  * FROM EMPLOYEE e; 
    
    BEGIN    
    
     FOR employee IN employees
      LOOP  
    
        is_found_rec := true;
    
            // do something  
    
      END LOOP; 
    
     if not is_found_rec then 
         // do something else 
     end if;
    
    END;
    

    【讨论】:

      【解决方案2】:

      我认为只有FETCH 才有可能。尝试使用

      if myCursor%found then
      // some body
      end if;
      

      但是如果有人知道另一种方法,请纠正我。

      【讨论】:

      【解决方案3】:

      我喜欢这种方式:

      DECLARE
      
          CURSOR my_cur
          IS
          SELECT 'a' AS a FROM DUAL WHERE 1=1;
      
          my_rec my_cur%rowtype;
      
      BEGIN
          OPEN my_cur;
          LOOP
      
              FETCH my_cur INTO my_rec;
      
              IF my_cur%NOTFOUND
              THEN
                  IF my_cur%ROWCOUNT=0
                  THEN
                      -- do stuff when cursor empty
                      DBMS_OUTPUT.PUT_LINE('NOTFOUND,RC=0' || '_' || my_cur%ROWCOUNT || '_' || my_rec.a);
                  END IF;
                  EXIT;
              ELSE
                      -- do stuff when cursor not empty
                  DBMS_OUTPUT.PUT_LINE('FOUND,RC>0' || '_' || my_cur%ROWCOUNT || '_' || my_rec.a);
              END IF;
      
          END LOOP;
          CLOSE MY_CUR;
      END;
      

      光标为 1=1(非空)时的输出:

      FOUND,RC>0_1_a
      

      光标为 1=0(空)时的输出:

      NOTFOUND,RC=0_0_
      

      【讨论】:

        【解决方案4】:

        我喜欢使用包含游标的相同选择查询并选择它返回到变量中的计数。然后,您可以评估变量以确定下一步要做什么。例如你有一个这样的光标:

        CURSOR c_example IS 
            SELECT field1
                ,field2
                ,field3
            FROM table1 a
            WHERE a.field1 LIKE '%something%';
        

        在你打开游标做任何处理之前,选择游标结果计数到一个变量中。

        SELECT count(*)
        INTO v_exampleCount
        FROM table1 a
        WHERE a.field1 LIKE '%something%';
        

        现在,在打开光标之前,请执行以下操作:

        IF exampleCount>0 THEN
        
            FOR example IN c_example
            LOOP
                ....
            END LOOP;  --end example loop
        
            ....
        
        END IF;  --end example if
        

        【讨论】:

          【解决方案5】:

          341/5000 一种解决方案是使用反向逻辑。它是例如不能问:

          IF my_record IS NULL THEN
             do something;
          END IF;
          

          IF my_record.my_attibute IS NULL THEN
             do something;
          END IF;
          

          反而可以问:

          IF my_record.my_attibute IS NOT NULL THEN
             go on processing;
          ELSE
             do something;
          END IF;
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2021-06-18
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2010-10-22
            • 2011-03-27
            • 2011-05-22
            • 2013-09-01
            相关资源
            最近更新 更多