PRAGMA EXCEPTION_INIT

PRAGMA EXCEPTION_INIT将用户定义的错误代码与异常相关联。PRAGMA EXCEPTION_INIT声明可包含在任何块、子块或包中。只能在声明异常后将错误代码分配给该异常(使用PRAGMA EXCEPTION_INIT)。

语法

PRAGMA EXCEPTION_INIT声明的格式如下:

PRAGMA EXCEPTION_INIT(exception_name,
                      {exception_number | exception_code})

其中:

  • exception_name是关联异常的名称。

  • Exception_number是用户定义的错误代码,与pragma关联。如果您指定未映射的exception_number,服务器将返回一条警告。

  • Exception_code是预定义异常的名称。有关有效异常的完整列表,请参见Postgres 核心文档

示例

  • 用户定义的异常中提供了一个示例,其中演示了如何在包中声明用户定义的异常。以下示例使用了相同的基本结构,新增了PRAGMA EXCEPTION_INIT声明:

    CREATE OR REPLACE PACKAGE ar AS
      overdrawn EXCEPTION;
      PRAGMA EXCEPTION_INIT (overdrawn, -20100);
      PROCEDURE check_balance(p_balance NUMBER, p_amount NUMBER);
    END;
    
    CREATE OR REPLACE PACKAGE BODY ar AS
       PROCEDURE check_balance(p_balance NUMBER, p_amount  NUMBER)
       IS
       BEGIN
           IF (p_amount > p_balance) THEN
             RAISE overdrawn;
           END IF;
        END;
    END;
  • 以下存储过程 (purchase) 调用check_balance存储过程。如果p_amount大于p_balance,则check_balance会引发异常,purchase会捕获ar.overdrawn异常。

    CREATE PROCEDURE purchase(customerID int, amount NUMERIC)
    AS
      BEGIN
         ar.check_balance(getcustomerbalance(customerid), amount);
           record_purchase(customerid, amount);
      EXCEPTION
         WHEN ar.overdrawn THEN
          DBMS_OUTPUT.PUT_LINE ('This account is overdrawn.');
          DBMS_OUTPUT.PUT_LINE ('SQLCode :'||SQLCODE||' '||SQLERRM );
    END;

    ar.check_balance引发异常时,执行会跳到purchase中定义的异常处理程序。

    EXCEPTION
         WHEN ar.overdrawn THEN
          DBMS_OUTPUT.PUT_LINE ('This account is overdrawn.');
          DBMS_OUTPUT.PUT_LINE ('SQLCode :'||SQLCODE||' '||SQLERRM );

    该异常处理程序会返回一条错误消息,后跟SQLCODE信息:

    This account is overdrawn.
    SQLCODE: -20100 User-Defined Exception
  • 以下示例演示了如何使用预定义的异常。代码为no_data_found异常创建了一个更有意义的名称,如果给定的客户不存在,代码会捕获异常,调用DBMS_OUTPUT.PUT_LINE以报告错误,然后重新引发原始异常:

    CREATE OR REPLACE PACKAGE ar AS
      unknown_customer EXCEPTION;
      PRAGMA EXCEPTION_INIT (unknown_customer, no_data_found);
      PROCEDURE check_balance(p_customer_id NUMBER);
    END;
    
    CREATE OR REPLACE PACKAGE BODY ar AS
       PROCEDURE check_balance(p_customer_id NUMBER)
       IS
       DECLARE
         v_balance NUMBER;
       BEGIN
         SELECT balance INTO v_balance FROM customer
           WHERE cust_id = p_customer_id;
       EXCEPTION WHEN unknown_customer THEN
         DBMS_OUTPUT.PUT_LINE('invalid customer id');
         RAISE;
       END;
    END;