Oracle PL/SQL多条DROP TRIGGER语句仅删除首个触发器的问题
问题原因
你把异常处理写在了整个代码块的最外层,而PL/SQL的执行逻辑是:当前块一旦抛出异常,进入异常分支处理完成后,会直接结束整个当前块,不会返回异常发生点之后继续执行剩余代码。
这就导致:
- 如果
trigger1不存在,第一行DROP语句直接抛出ORA-04080(触发器不存在)错误,马上进入外层异常处理,判断错误码符合预期就不抛出,整个代码块直接结束,后面两个触发器的删除逻辑根本不会执行 - 如果
trigger1存在被成功删除,但trigger2不存在,第二行DROP抛错后同样会直接进入异常分支结束代码块,trigger3的删除也不会执行
这就是你遇到的只能删除第一个触发器的核心原因。
修正方案
给每一个DROP TRIGGER语句套独立的子块,让每个删除操作单独处理自己的异常,单个触发器不存在的报错不会打断其他删除逻辑的执行:
BEGIN -- 删除第一个触发器 BEGIN EXECUTE IMMEDIATE 'DROP TRIGGER trigger1'; EXCEPTION WHEN OTHERS THEN IF SQLCODE != -4080 THEN RAISE; END IF; END; -- 删除第二个触发器 BEGIN EXECUTE IMMEDIATE 'DROP TRIGGER trigger2'; EXCEPTION WHEN OTHERS THEN IF SQLCODE != -4080 THEN RAISE; END IF; END; -- 删除第三个触发器 BEGIN EXECUTE IMMEDIATE 'DROP TRIGGER trigger3'; EXCEPTION WHEN OTHERS THEN IF SQLCODE != -4080 THEN RAISE; END IF; END; END; /
如果你使用的是Oracle 12cR2及以上版本,不需要手动编写异常捕获逻辑,直接用原生支持的
IF EXISTS语法即可,代码更简洁:BEGIN EXECUTE IMMEDIATE 'DROP TRIGGER IF EXISTS trigger1'; EXECUTE IMMEDIATE 'DROP TRIGGER IF EXISTS trigger2'; EXECUTE IMMEDIATE 'DROP TRIGGER IF EXISTS trigger3'; END; /
内容的提问来源于stack exchange,提问作者user1312312
相关产品推荐
相关产品推荐

