约束违反异常PL / SQL

时间:2018-03-04 20:27:03

标签: oracle exception plsql constraints

我目前正在进行一项任务,我需要创建一个匿名块来处理约束违规(违规是更新后的信用卡数量太少)。我创建了以下没有错误的块,它只返回约束违规。知道为什么它不能提高我的例外吗?

DECLARE 
my_excep EXCEPTION;
BEGIN
UPDATE mm_member
SET credit_card = '123456789'
WHERE member_id = '14';
IF SQL%ROWCOUNT = 0 THEN
RAISE my_excep;
END IF;
EXCEPTION
WHEN my_excep THEN
DBMS_OUTPUT.PUT_LINE('Failed to update.');
END;

继承人创建表

CREATE TABLE mm_member
(member_id  NUMBER(4),
last         VARCHAR(12),
first        VARCHAR(8),
license_no   VARCHAR(9),
license_st   VARCHAR(2),
credit_card  VARCHAR(12),
suspension   VARCHAR(1) DEFAULT 'N',
mailing_list VARCHAR(1),
CONSTRAINT cust_custid_pk PRIMARY KEY (member_id),
CONSTRAINT cust_credcard_ck CHECK (LENGTH(credit_card) = 12));

executed block

1 个答案:

答案 0 :(得分:0)

您编写的代码完全符合预期 - 如果它没有更新任何内容,它会引发一个异常,只执行DBMS_OUTPUT.PUT_LINE并显示"无法更新"。

你期望它做什么?

如果您打算实际引发异常,您应该已经完成​​了它(而不是DBMS_OUTPUT):

raise_application_error(-20000, 'Failed to update');

尽管如此,你所写的内容与你所描述的无关,即

  

违规是更新的信用卡数量太少

这可以使用真实约束完成,例如

create table  mm_member
  ( member_id  varchar2(2)
    credit_card varchar2(20) constraint ch_cc check (length(credit_card) = 9),
  );

虽然在我看来这似乎是一个非常低效的检查。

[编辑:举起示威]

SQL> create table  mm_member
  2    ( member_id  varchar2(2),
  3      credit_card varchar2(20)
  4    );

Table created.

SQL> insert into mm_member (member_id, credit_card) values ('14', '1234');

1 row created.

SQL> -- this will work because there's MEMBER_ID = 14 in the table
SQL> DECLARE
  2    my_excep EXCEPTION;
  3  BEGIN
  4    UPDATE mm_member
  5      SET credit_card = '123456789'
  6      WHERE member_id = '14';
  7
  8    IF SQL%ROWCOUNT = 0 THEN
  9       RAISE my_excep;
 10    END IF;
 11  EXCEPTION
 12    WHEN my_excep THEN
 13      --DBMS_OUTPUT.PUT_LINE('Failed to update.');
 14      raise_application_error(-20000, 'Failed to update');
 15  END;
 16  /

PL/SQL procedure successfully completed.

行;现在失败了:

SQL> -- changing '14' to something else (for example, '15') will raise an exception
SQL> l6
  6*     WHERE member_id = '14';
SQL> c/14/15
  6*     WHERE member_id = '15';
SQL> /
DECLARE
*
ERROR at line 1:
ORA-20000: Failed to update    --> see? This is an exception
ORA-06512: at line 14


SQL>

[编辑#2:拦截检查约束违规]

由于检查约束违规,这将失败:注意ORA-02290错误代码:

SQL> update mm_member set credit_card = '123';
update mm_member set credit_card = '123'
*
ERROR at line 1:
ORA-02290: check constraint (SCOTT.CH_CC) violated

您的代码经过修改以通过声明{em}使用相同的2290错误代码PRAGMA EXCEPTION_INIT来拦截它:

SQL> DECLARE
  2    my_excep EXCEPTION;
  3    pragma exception_init (my_excep, -2290);
  4  BEGIN
  5    UPDATE mm_member
  6      SET credit_card = '123456789'
  7      WHERE member_id = '14';
  8
  9    IF SQL%ROWCOUNT = 0 THEN
 10       RAISE my_excep;
 11    END IF;
 12  EXCEPTION
 13    WHEN my_excep THEN
 14      DBMS_OUTPUT.PUT_LINE('I intercepted check constraint - failed to update.');
 15  END;
 16  /
I intercepted check constraint - failed to update.

PL/SQL procedure successfully completed.

SQL>