很难找出与光标一起使用的最佳属性

时间:2018-03-27 13:48:05

标签: sql oracle plsql

在此光标中使用此属性%NOTFOUND会给我带来问题。我也尝试过使用%FOUND。有更好的选择吗?它继续返回Else,即使光标带回来还是没有。如果光标有东西,我希望它发送第一封电子邮件,如果光标没有,我希望它发送第二封电子邮件。

CURSOR crs IS
 select *
 from user_objects
 where status = 'INVALID';
BEGIN

 OPEN crs;

Loop

  FETCH crs bulk collect INTO messages limit 10;
  EXIT WHEN message. count = '0';

 End IF;

  for indx in     messages.FIRST .. messages.LAST
  loop 
    email_body := email_body||CHR(10)||'OBJECT NAME: '||messages(indx).OBJECT_NAME||', OBJECT TYPE: '||messages(indx). OBJECT_TYPE||', STATUS: '||messages(indx).STATUS;
  end loop;
END LOOP;



 IF CRS%NOTFOUND THEN
     Email_body := email_body||CHR(10)|| '' ||CHR(10)||'All of these objects are invalid in your database. Please troubleshoot the issue. Thank you.'
     DBMS_OUTPUT_LINE(email_body||'Invalid obj.';
    ELSE 
     Email_body := 'There are no invalid objects in your database. Thank You.';
      DBMS_OUTPUT_LINE(email_body||'No Invalid obj.';
    END IF;

2 个答案:

答案 0 :(得分:3)

您可以尝试进行测试(我认为更具可读性和更短):

declare
    email_body varchar2( 4000 ) := '';
    l_invalid_objects_list varchar2( 4000 ) := '';
begin
l_invalid_objects_list := '';
for i in ( select OBJECT_NAME, OBJECT_TYPE, STATUS from user_objects where status = 'INVALID' and rownum <= 10 ) --limited to 10 records
loop
    l_invalid_objects_list := l_invalid_objects_list||CHR(10)||'OBJECT NAME: '||i.OBJECT_NAME||', OBJECT TYPE: '||i. OBJECT_TYPE||', STATUS: '||i.STATUS;
end loop;
if length( l_invalid_objects_list ) > 0 then 
    email_body := email_body||CHR(10)|| '' ||CHR(10)||l_invalid_objects_list||CHR(10)|| '' ||CHR(10)||'All of these objects are invalid in your database. Please troubleshoot the issue. Thank you.';
    DBMS_OUTPUT.PUT_LINE(email_body||'Invalid obj.');
else
    Email_body := 'There are no invalid objects in your database. Thank You.';
    DBMS_OUTPUT.PUT_LINE(email_body||'No Invalid obj.');
end if;
end;

答案 1 :(得分:0)

我假设您想要使用批量操作,并且您希望以10个批次执行此操作,即使它可能对功能有点过分。 所以。 。 。你需要根据游标(ROWTYPE)声明一个表类型,然后根据类型声明一个变量。 您想要为每个对象添加到email_body,当您在该批次中循环时,您似乎想要另一条消息说明是否存在任何无效对象。

使用%NOTFOUND不在此处,因为当messages.COUNT = 0时退出循环。当它为0时,光标将始终为%NOTFOUND,因此您始终获得INVALID选项。 我已经使用了一个布尔值,只要你有至少一个无效对象并且检查了它而不是%NOTFOUND,就会设置为TRUE。

DECLARE
   CURSOR crs
   IS
      SELECT *
      FROM   user_objects
      WHERE  status = 'INVALID';

   TYPE work_recs IS TABLE OF crs%ROWTYPE;
   messages work_recs;

   lbol_invalid_objects BOOLEAN := FALSE;
   email_body  VARCHAR2(2000);

BEGIN
   OPEN crs;

   LOOP
      FETCH crs BULK COLLECT INTO messages LIMIT 10;

      DBMS_OUTPUT.PUT_LINE('COUNT - '||messages.COUNT);

      EXIT WHEN messages.COUNT = '0';

      lbol_invalid_objects := TRUE;

      FOR indx IN messages.FIRST .. messages.LAST
      LOOP
         email_body := email_body||CHR(10)||'OBJECT NAME: '||messages(indx).OBJECT_NAME||', OBJECT TYPE: '||messages(indx). OBJECT_TYPE||', STATUS: '||messages(indx).STATUS;
      END LOOP;
   END LOOP;

   IF lbol_invalid_objects THEN
      email_body := email_body||CHR(10)|| '' ||CHR(10)||'All of these objects are invalid in your database. Please troubleshoot the issue. Thank you.'
      dbms_output.put_line('Invalid obj.');
   ELSE
      email_body := 'There are no invalid objects in your database. Thank You.';
      dbms_output.put_line('No Invalid obj.');
   END IF;
END;