具有IF条件的PL / SQL游标

时间:2014-10-01 14:53:17

标签: sql oracle stored-procedures plsql

我在代码中有光标。

   CURSOR cur1
   IS
      SELECT a, b, c, d,
        FROM EMP;
BEGIN
    --Stored procedure logic
END

这个curosr正在从EMP表中获取信息。

但我需要改变如下

  
      
  • 有一个表(表1),其中包含键值对。
  •   
  • 如果Table1值为TRUE,则应使用STUDENT表
  • 创建光标   
  • 如果table1值为FALSE,则应使用EMP表创建游标。
  •   

我可以查看表1中的值,如下所示

select t.value into variable1 from Table1 t where s.key='xxxxx';

我希望写一些类似

的内容
IF variable1 := 'true'
 curosr created with STUDENT
 ELSE
  curosr created with EMP
END IF

BEGIN
    --Stored procedure logic
END

怎么做?

5 个答案:

答案 0 :(得分:1)

使用if .. else构造不合适(不支持)。您可以使用REF cursor来实现同样的目标。

 DECLARE type cur1 REF CURSOR;
 c1 cur1;

  BEGIN 
   IF (variable1 := 'true') THEN 
     OPEN c1 FOR 'SELECT * FROM STUDENT'; 
   ELSE 
     OPEN c1 FOR 'SELECT * FORM EMP';
 END IF ; 
  END; 

来自Oracle Community Forum Post

的想法

注意:我没有包含整个代码块(我的意思是光标处理,关闭等),因为这里主要关注的是“他将如何声明/定义条件游标”。所以,特别指出我的代码片段。因为,处理光标和关闭的其余部分可以直接在Oracle规范中找到。

对于完整的代码块,您可以参考Harsh

给出的答案

答案 1 :(得分:1)

我更愿意在不使用动态SQL的情况下解决这个问题。如果处理结果的代码对于两个表都是相同的,那么可以合理地假设列也是相同的(或等效的)。我倾向于使用UNION和子查询来解决这个问题:

DECLARE
   CURSOR cur1 IS
      SELECT a, b, c, d
      FROM   emp
      WHERE  NOT EXISTS
                (SELECT *
                 FROM   table1
                 WHERE  s.key = 'xxxxx' AND t.VALUE = 'true')
      UNION ALL
      SELECT a, b, c, d
      FROM   student
      WHERE  EXISTS
                (SELECT *
                 FROM   table1
                 WHERE  s.key = 'xxxxx' AND t.VALUE = 'true');
BEGIN
  --Stored procedure logic
END;

答案 2 :(得分:0)

Rahul提供的链接指出了解决问题的正确方法。在Rahul发布的Oracle社区论坛帖子中,我已经获取了代码片段,代码可以成功运行。

Rahul:请不要将此作为一个多余的答案,因为我无法评论您的答案,以帮助shyam在您发布的链接中获取代码段。

    Declare

TYPE cv_typ IS REF CURSOR;
     cv cv_typ;

Begin
If(condition1 is TRUE) then
     open cv FOR
     'Select * from table_name1';
     EXIT WHEN cv%NOTFOUND;
ELSE
     open cv FOR
     'Select * from table_name2';
     EXIT WHEN cv%NOTFOUND;

End If;

     CLOSE cv;
END; 

谢谢&问候, 苛刻

答案 3 :(得分:0)

以另一种方式,您可以只为这两种情况保留两个CURSORS,并在条件下将其打开。声明两个CURSORS不会影响性能;您应该在打开游标并从中进行抓取时要小心。

PROCEDURE Get_Details_On_Condition ( name_ OUT VARCHAR2, isEmp IN BOOLEAN )
IS
  CURSOR get_emp IS
     SELECT name
     FROM EMP;
  CURSOR get_std IS
     SELECT name
     FROM STUDENT;
BEGIN
   IF isEmp THEN
      OPEN get_emp ;
      FETCH get_emp INTO name_ ;
      CLOSE get_emp ;
   ELSE
      OPEN get_std ;
      FETCH get_std INTO name_ ;
      CLOSE get_std ;
   END IF;
RETURN name_;
END Get_Details_On_Condition;

答案 4 :(得分:0)

您可以将 OPEN 移到 IF 语句之外:

    DECLARE type cur1 REF CURSOR;
    c1 cur1;

    vSQL VARCHAR2(1000);

    BEGIN
        IF (variable1 = 'true') THEN 
            vSQL := 'SELECT * FROM STUDENT'; 
        ELSE 
            vSQL := 'SELECT * FORM EMP';
        END IF; 
        OPEN c1 FOR vSQL;
        --procedure logic
        CLOSE c1;
    END;