Oracle 游标Select语句,其中条件根据条件更改

Oracle 游标Select语句,其中条件根据条件更改,oracle,select,cursor,conditional-statements,Oracle,Select,Cursor,Conditional Statements,我在一个过程中使用游标,这里我不使用批量收集,因为我对从游标获取的记录进行了大量计算 在Cursor的Select语句Where子句根据条件更改时,我尝试使用以下代码,但它给了我错误: 错误(19,12):PLS-00103:在预期以下情况之一时遇到符号“c_recs”:=。(@% 我不想使用SYS_REFCURSOR,因为从网络上看,我读到的游标比ref游标稍微好一些。游标声明中的CASE解决了这个问题: DECLARE CURSOR c_recs IS SELECT

我在一个过程中使用游标,这里我不使用批量收集,因为我对从游标获取的记录进行了大量计算

在Cursor的Select语句Where子句根据条件更改时,我尝试使用以下代码,但它给了我错误:

错误(19,12):PLS-00103:在预期以下情况之一时遇到符号“c_recs”:=。(@%


我不想使用SYS_REFCURSOR,因为从网络上看,我读到的游标比ref游标稍微好一些。

游标声明中的CASE
解决了这个问题:

DECLARE
   CURSOR c_recs
   IS
      SELECT cname
        FROM a_aud aa
       WHERE     aa.time BETWEEN TO_DATE (fromdate_in, 'dd/mm/rrrr')
                             AND TO_DATE (todate_in, 'dd/mm/rrrr')
             AND aa.ctype =
                    CASE
                       WHEN atype_in = '01' THEN 'RAlert'
                       WHEN atype_in = '02' THEN 'DAlert'
                    END;
BEGIN
   FOR rec IN c_recs
   LOOP
      NULL;
   END LOOP;
END;

我无法评论您的refcursor语句。

游标声明中的CASE
解决了该问题:

DECLARE
   CURSOR c_recs
   IS
      SELECT cname
        FROM a_aud aa
       WHERE     aa.time BETWEEN TO_DATE (fromdate_in, 'dd/mm/rrrr')
                             AND TO_DATE (todate_in, 'dd/mm/rrrr')
             AND aa.ctype =
                    CASE
                       WHEN atype_in = '01' THEN 'RAlert'
                       WHEN atype_in = '02' THEN 'DAlert'
                    END;
BEGIN
   FOR rec IN c_recs
   LOOP
      NULL;
   END LOOP;
END;

我无法对您的refcursor语句进行评论。

更好、更有效的方法是在一条语句中执行此操作,而不使用任何游标。但是,这取决于您要执行的操作。如果必须基于游标记录执行DML,最好在一条语句中执行

如果确实希望在循环中处理某些内容,请使用与显式游标等效(有时性能更好)的隐式游标循环

还可以使用条件逻辑而不是IF/ELSE简化select查询

CREATE OR REPLACE PROCEDURE "test" (
     fromdate_in   IN VARCHAR2,
     todate_in     IN VARCHAR2,
     atype_in
          in NUMBER
) is begin 

for cur in (
     SELECT cname
     FROM a_aud aa
     WHERE aa.time BETWEEN TO_DATE(fromdate_in,'dd/mm/rrrr') 
     AND TO_DATE(todate_in,'dd/mm/rrrr') AND (
          (
               atype_in = '01' AND aa.ctype = 'RAlert'
          ) OR (
               atype_in = '02' AND aa.ctype = 'DAlert'
          )
     )
) loop
                         ---calculations
    do_something_with(cur.cname)
   end loop;
 end;  
 /

我还建议您将参数类型设置为日期,并直接从调用块传递变量,而不是在sql/cursor中进行转换。这将避免
到日期的转换。

一个更好、更有效的选择是在单个语句中进行转换,而不使用任何游标。但是,这取决于如果必须基于游标记录执行DML,最好在单个语句中执行

如果确实希望在循环中处理某些内容,请使用与显式游标等效(有时性能更好)的隐式游标循环

还可以使用条件逻辑而不是IF/ELSE简化select查询

CREATE OR REPLACE PROCEDURE "test" (
     fromdate_in   IN VARCHAR2,
     todate_in     IN VARCHAR2,
     atype_in
          in NUMBER
) is begin 

for cur in (
     SELECT cname
     FROM a_aud aa
     WHERE aa.time BETWEEN TO_DATE(fromdate_in,'dd/mm/rrrr') 
     AND TO_DATE(todate_in,'dd/mm/rrrr') AND (
          (
               atype_in = '01' AND aa.ctype = 'RAlert'
          ) OR (
               atype_in = '02' AND aa.ctype = 'DAlert'
          )
     )
) loop
                         ---calculations
    do_something_with(cur.cname)
   end loop;
 end;  
 /

我还建议您将参数类型作为日期,并直接从调用块传递变量,而不是在sql/游标中转换。这将避免
到日期的转换。

谢谢Nayak,我使用了这个解决方案谢谢Nayak,我使用了这个解决方案谢谢Littlefoot,答案是有用的谢谢Littlefoot,一个斯韦尔很有用