PRAGMA EXCEPTION_INIT仅支持Oracle内置错误号(如-60、-1400),不支持RAISE_APPLICATION_ERROR自定义码(如-20998),否则编译报PLS-00707;自定义错误须用WHEN OTHERS配合SQLCODE判断。

PRAGMA EXCEPTION_INIT 不能绑定自定义负数错误码,因为它只接受 Oracle 内部已定义的错误号(即真实发生的 ORA- 错误对应的数字),比如 -60、-1400、-1476。你给它传一个没在 Oracle 错误体系里注册过的负数(例如 -20998),编译器会直接报错:PLS-00707 — “Unsupported error number”。
这不是语法写错了,是语义不合法。
哪些错误号能用 PRAGMA EXCEPTION_INIT 绑定?
-
必须是 Oracle 运行时实际抛出过的错误编号(带负号),比如:
-
-60(deadlock detected) -
-1400(cannot insert NULL) -
-1476(divisor is equal to zero) -
-100(NO_DATA_FOUND 的内部码,但注意:它属于预定义异常,通常不推荐再用 PRAGMA 绑)
-
-
不能是:
- 你自己用
RAISE_APPLICATION_ERROR(-20998, ...)定义的业务错误码 - 任意捏造的负数,如
-20001、-99999 - 正数或零
- 你自己用
那自定义错误码怎么捕获?
必须用 WHEN OTHERS + SQLCODE 判断,或者直接靠上层应用识别 ORA-20998 字符串。例如:
EXCEPTION
WHEN OTHERS THEN
IF SQLCODE = -20998 THEN
DBMS_OUTPUT.PUT_LINE('业务校验失败');
-- 自定义处理逻辑
ELSE
RAISE; -- 其他错误继续上抛
END IF;
为什么设计成这样?
PRAGMA EXCEPTION_INIT 是编译期指令,作用是把「已知的系统错误事件」映射到一个局部异常变量名,让 WHEN exception_name 能精准分支。而 RAISE_APPLICATION_ERROR 抛出的是用户级逻辑错误,不属于 Oracle 的错误事件分类体系,编译器无法在编译时建立这种映射。
真正容易被忽略的一点是:很多人以为只要写了 PRAGMA EXCEPTION_INIT(my_err, -20998),就能像捕获 -60 那样用 WHEN my_err 捕获自定义错误 —— 实际上这行 pragma 本身就会编译失败,根本跑不到运行时。


















