【问题标题】:PL/SQL no data found exception handlingPL/SQL 找不到数据异常处理
【发布时间】:2017-02-14 11:02:07
【问题描述】:

我有一个 EMAILS 表,其中包含以下列:ROUTINE、EMAILS 和 COPIES,它们定义了应该使用 UTL_MAIL 将特定过程的结果发送给谁(至/cc)。

我有以下代码:

PROCEDURE myproc AS
  NO_EMAIL_FOUND EXCEPTION;
  e EMAILS%ROWTYPE;
  x NUMBER;
BEGIN

  --fetch data
  SELECT x INTO x FROM <...>;

  --fetch emails
  SELECT * INTO e FROM emails WHERE routine='FRS_WEEKLY';
  IF e.emails IS NULL AND e.copies IS NULL THEN
    RAISE NO_EMAIL_FOUND;
  END IF;

  <send mail code using UTL_MAIL>;

  EXCEPTION
    WHEN NO_EMAIL_FOUND THEN <code1>;
    WHEN NO_DATA_FOUND THEN <code2>;
    WHEN OTHERS THEN NULL; --RAISE;

END myproc;

我希望 myproc 在 EMAILS 表中没有电子邮件时执行 code1。我的问题是没有引发 NO_EMAIL_FOUND 异常并且 code2 执行,因为在 SELECT 语句中引发了 NO_DATA_FOUND 异常。如何避免这种情况?

【问题讨论】:

    标签: oracle plsql


    【解决方案1】:

    试试这个:

    PROCEDURE myproc AS
        NO_EMAIL_FOUND EXCEPTION;
        e EMAILS%ROWTYPE;
        x NUMBER;
    BEGIN
    
        BEGIN
            --fetch data
            SELECT x INTO x FROM <...>;
    
            --fetch emails
            BEGIN
                SELECT * INTO e FROM emails WHERE routine='FRS_WEEKLY';
            EXCEPTION WHEN NO_DATA_FOUND THEN
                RAISE NO_EMAIL_FOUND;
            END;
            IF e.emails IS NULL AND e.copies IS NULL THEN
                RAISE NO_EMAIL_FOUND;
            END IF;
    
            <send mail code using UTL_MAIL>;
    
        EXCEPTION
            WHEN NO_EMAIL_FOUND THEN <code1>;
            WHEN NO_DATA_FOUND THEN <code2>;
            WHEN OTHERS THEN NULL; --RAISE;
        END;
    
    END myproc;
    

    【讨论】:

    • 是的,解决方案是将我的 SELECT 封装到内部 BEGIN EXCEPTION END 结构中,在内部捕获 NO_DATA_FOUND,并根据需要将其传播到 NO_EMAIL_FOUND,最后捕获它。 IF e.emails IS NULL ... 则不再需要。谢谢。
    【解决方案2】:

    使用这个:

    PROCEDURE myproc AS
      NO_EMAIL_FOUND EXCEPTION;
      e EMAILS%ROWTYPE;
      x NUMBER;
    BEGIN
    
      --fetch data
      SELECT x INTO x FROM <...>;
    
      --fetch emails
      BEGIN
        SELECT * INTO e FROM emails WHERE routine='FRS_WEEKLY';
      EXCEPTION
        WHEN NO_DATA_FOUND THEN
          RAISE NO_EMAIL_FOUND;
      END;
    
      IF e.emails IS NULL AND e.copies IS NULL THEN
        RAISE NO_EMAIL_FOUND;
      END IF;
    
      <send mail code using UTL_MAIL>;
    
      EXCEPTION
        WHEN NO_EMAIL_FOUND THEN <code1>;
        WHEN NO_DATA_FOUND THEN <code2>;
        WHEN OTHERS THEN NULL; --RAISE;
    
    END myproc;
    

    我希望您知道此例程只能处理一封电子邮件;如果有多个,则会引发 TOO_MANY_ROWS 异常。

    【讨论】:

    • 列 'routine' 是我的 EMAILS 表中的 PK,因此不会有 TOO_MANY_ROWS(每个过程执行一条记录和一封邮件)。当然,一封电子邮件,但有更多的电子邮件地址。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-01-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多