CURSOR FOR LOOP 返回的查询数据

Posted

技术标签:

【中文标题】CURSOR FOR LOOP 返回的查询数据【英文标题】:Query data returned by CURSOR FOR LOOP 【发布时间】:2017-04-04 09:25:38 【问题描述】:

我需要以下 PL/SQL 代码的帮助,该代码显示两个日期值之间的时间差(以分钟为单位)。 IF 语句之前的第一部分返回所需的信息,但是当我尝试编写 IF 语句以仅显示那些超过 15 分钟的作业的时差然后通过 Exchange Server 发送电子邮件通知时,挑战就来了.

提前感谢您的帮助。

Declare

l_found boolean :=false;

Cursor C5 

is 
    (SELECT CASE LENGTH(JCSBMTIME) 
     WHEN 0 THEN
     round(((sysdate - to_date 
     (TO_DATE(TO_CHAR(to_number(JCSBMDATE)+1900000),'YYYYDDD') || ' ' ||  
     to_char(to_date(CONCAT('000000',JCSBMTIME),'HH24:MI:SS'),'HH24:MI:SS')  
     ,'DD-MON-YY HH24:MI:SS')) * 1440),2)
     WHEN 1 THEN
     round(((sysdate - to_date 
     (TO_DATE(TO_CHAR(to_number(JCSBMDATE)+1900000),'YYYYDDD') || ' ' ||  
     to_char(to_date(CONCAT('00000',JCSBMTIME),'HH24:MI:SS'),'HH24:MI:SS')  
     ,'DD-MON-YY HH24:MI:SS')) * 1440),2)
     WHEN 2 THEN
     round(((sysdate - to_date 
     (TO_DATE(TO_CHAR(to_number(JCSBMDATE)+1900000),'YYYYDDD') || ' ' ||  
     to_char(to_date(CONCAT('0000',JCSBMTIME),'HH24:MI:SS'),'HH24:MI:SS')  ,'DD-
     MON-YY HH24:MI:SS')) * 1440),2)
     WHEN 3 THEN
     round(((sysdate - to_date 
     (TO_DATE(TO_CHAR(to_number(JCSBMDATE)+1900000),'YYYYDDD') || ' ' ||  
     to_char(to_date(CONCAT('000',JCSBMTIME),'HH24:MI:SS'),'HH24:MI:SS')  ,'DD-
     MON-YY HH24:MI:SS')) * 1440),2)
     WHEN 4 THEN
     round(((sysdate - to_date 
     (TO_DATE(TO_CHAR(to_number(JCSBMDATE)+1900000),'YYYYDDD') || ' ' ||  
     to_char(to_date(CONCAT('00',JCSBMTIME),'HH24:MI:SS'),'HH24:MI:SS')  ,'DD-
     MON-YY HH24:MI:SS')) * 1440),2)
     WHEN 5 THEN
     round(((sysdate - to_date 
     (TO_DATE(TO_CHAR(to_number(JCSBMDATE)+1900000),'YYYYDDD') || ' ' ||  
     to_char(to_date(CONCAT('0',JCSBMTIME),'HH24:MI:SS'),'HH24:MI:SS')  ,'DD-
     MON-YY HH24:MI:SS')) * 1440),2)
     ELSE
     round(((sysdate - to_date 
     (TO_DATE(TO_CHAR(to_number(JCSBMDATE)+1900000),'YYYYDDD') || ' ' ||  
     to_char(to_date(CONCAT('',JCSBMTIME),'HH24:MI:SS'),'HH24:MI:SS')  ,'DD-MON-
     YY HH24:MI:SS')) * 1440 ),2)
     END AS "DATETIME_DIFF", 
     JCUSER, JCJOBNBR, JCSBMTIME FROM SVM900E1.F986110 
     WHERE JCSBMDATE = (TO_CHAR(sysdate,'YYYYDDD')-1900000) 
     AND JCJOBSTS in ('P','S','W')); 

Begin

    For Y in C5 

Loop 

l_found := true;

    dbms_output.put_line(Y.DATETIME_DIFF||' '||Y.JCUSER||' ' ||Y.JCJOBNBR||' 
    '||Y.JCSBMTIME); 
End loop;

if not l_found

Then

    dbms_output.put_line('No records found');

End if;

Case Y.DATETIME_DIFF  when > 15 

Then 

   dbms_output.put_line(Y.JCUSER||' ' ||Y.JCJOBNBR||' '||Y.JCSBMTIME);

Else 'No records';

End case;

End;

【问题讨论】:

有什么问题?你有错误'如果是这样,哪个?还是您有不良行为? 我还没有阅读所有代码,但是当您需要 IF 并且您从循环外部引用循环变量 Y 时,您正在尝试使用 CASE。另外,ELSE 应该怎么做? 【参考方案1】:

注意你的 Y 迭代器作用域。您正在尝试在循环语句之外使用它。

你的代码应该是这样的。我省略了游标声明的一部分 --首先初始化为假 l_found := false;

 for Y in your_cursor loop 
 -- if we are in loop , we are found a record , change value to true
 l_found := true;

  check conditions, do output etc...

 end loop;

-- if cursor have no result 
if not l_found then
    dbms_output.put_line('No records found');
end if;

【讨论】:

已将我的代码修改为如下所示,但现在它没有返回任何数据或消息。 修改了它,但现在程序执行然后什么也不返回 Begin For Y in C5 Loop --l_found := true; dbms_output.put_line(Y.DATETIME_DIFF||' '||Y.JCUSER||' ' ||Y.JCJOBNBR||' '||Y.JCSBMTIME);如果 Y.DATETIME_DIFF > 15 则 dbms_output.put_line(Y.JCUSER||' ' ||Y.JCJOBNBR||' '||Y.JCSBMTIME); else dbms_output.put_line('No records found: nothing above 15');万一; /*if not l_found Then dbms_output.put_line('No records found');结束 if;*/ 结束循环;结束; 如果你的游标没有结果集,那么你不能在循环内检查“if not l_found”表达式,它应该是检查循环运算符。 3.23 KALELIJ 2217639 83755 未找到记录:未超过 15 6.2 OMONDIR 2217635 83457 未找到记录:未超过 15 删除 l_found boolean :=false 部分后,这是我得到的输出。如果超过 15 分钟的数据可用,我不应该看到没有找到记录。 3.23 KALELIJ 2217639 83755 未找到记录:未超过 15 6.2 OMONDIR 2217635 83457 未找到记录:未超过 15

以上是关于CURSOR FOR LOOP 返回的查询数据的主要内容,如果未能解决你的问题,请参考以下文章

在 CURSOR FOR LOOP 中使用游标属性

pl sql cursor for loop in

需要帮助理解 Cursor for loop

Oracle存储过程中,查询结果有多行如何赋值

如何在 PL/SQL 中使用 BULK COLLECT 和 FORALL 替换 CURSOR FOR LOOP?

Oracle/PLSQL 在 BULK COLLECT 之后处理 for LOOP 中的所有数据