PL / SQL异常以什么顺序引发?

时间:2019-07-13 01:14:34

标签: oracle exception plsql

我正在尝试理解引发PL / SQL异常的顺序。这是我使用HR模式的代码:

DECLARE
  dept_to_delete departments.department_id%TYPE := 105;
  dept_to_keep departments.department_id%TYPE   := 115;

  integrity_constraint_violated EXCEPTION;
  PRAGMA EXCEPTION_INIT(integrity_constraint_violated, -2291);
  no_department_to_delete EXCEPTION;
BEGIN
  -- Will cause integrity_constraint_violated error
  UPDATE  employees
  SET     department_id = dept_to_keep
  WHERE   department_id = dept_to_delete;

  DELETE FROM departments
  WHERE department_id = dept_to_delete;
  IF SQL%NOTFOUND THEN
    RAISE no_department_to_delete;
  END IF;
EXCEPTION
  WHEN integrity_constraint_violated THEN
    DBMS_OUTPUT.PUT_LINE('Cannot assign employees to non-existing department.');
  WHEN no_department_to_delete THEN
    DBMS_OUTPUT.PUT_LINE('No such department to delete.');
END;

部门表中既没有部门ID 105也没有部门115。我的期望是首先引发integrity_contraint_violated异常,因为它首先出现在代码中,但是用户定义的no_department_to_delete首先被引发。输出为:

Cannot assign employees to non-existing department.

这是否有逻辑,还是不可能首先知道会引发哪个异常?

编辑 乔恩·海勒(Jon Heller)是对的。 UPDATE语句不会引起异常,因为WHERE子句会过滤掉所有记录。我搞砸了太久了。无论如何,可以得出的结论是, PL / SQL异常是根据它们发生的顺序而引发的,这很直观。很高兴知道。谢谢,乔恩。

1 个答案:

答案 0 :(得分:4)

PL / SQL异常的产生取决于其发生的顺序,而不是它们在EXCEPTION子句中的顺序。

UPDATE语句一定不能引发异常。 (如果确定的话,那么如果您使用minimal, reproducible example修改问题,我们可以解决。

此外,与问题没有直接关系,但我建议删除自定义异常处理。它没有提供任何有价值的东西。如果没有异常处理,该块将自动引发错误消息,对象名称和行号,这是调试问题的大量信息。使用自定义异常处理时,不存在对象名称和行号。如果未启用DBMS_OUTPUT,则不会看到该异常。