注册
报错“-7188包计划运行时失效”,包含rename场景下如何改写绕过
技术分享/ 文章详情 /

报错“-7188包计划运行时失效”,包含rename场景下如何改写绕过

I丶Sheng 2026/06/18 288 0 0

背景:
国产化改造过程中,原业务大量使用plsql的场景下,遇到“包计划运行时失效”的问题,某些情况下,可以通过简单的改写绕过这类报错。

案例:
1、创建测试数据,两张表结构相同

create table table_a (name varchar2(20)); create table table_temp (name varchar2(20));

2、创建包,包中包含两个存储过程

CREATE OR REPLACE PACKAGE PKG_TEST IS PROCEDURE P_SEL();--查询数据 PROCEDURE P_DATA_EX();--数据交换 END PKG_TEST; CREATE OR REPLACE PACKAGE BODY PKG_TEST IS PROCEDURE P_SEL() IS BEGIN SELECT * FROM TABLE_A; END; PROCEDURE P_DATA_EX() IS BEGIN EXECUTE IMMEDIATE 'TRUNCATE TABLE TABLE_TEMP'; EXECUTE IMMEDIATE 'ALTER TABLE TABLE_A RENAME TO TABLE_B'; EXECUTE IMMEDIATE 'ALTER TABLE TABLE_TEMP RENAME TO TABLE_A'; EXECUTE IMMEDIATE 'ALTER TABLE TABLE_B RENAME TO TABLE_TEMP'; END; END;

3、通过匿名块模拟业务顺序调用包内存储过程

BEGIN PKG_TEST.P_SEL(); PKG_TEST.P_DATA_EX(); PKG_TEST.P_SEL(); END; 执行失败(语句1) -7188: 包计划运行时失效

在数据库底层机制中,RENAME 操作会直接修改对象在系统目录表(如 SYSOBJECTS)中的唯一标识符(ID)。由于包内对象之间通过依赖关系表(如 SYSDEPENDENCIES)相互绑定,一旦目标对象的 ID 发生变更,原有的依赖链路即被破坏,导致整个包进入失效状态。
这种失效状态会进一步波及匿名块的执行。因为匿名块的执行计划是在运行前预先编译生成的,当块内按顺序调用的存储过程因上述 RENAME 操作而失去有效性时,匿名块原先缓存的执行计划便随之失效,从而无法继续正常执行。

绕过方法
1、创建存储过程,处理数据交换,不在包内执行

create or REPLACE PROCEDURE pro_data_ex() IS BEGIN EXECUTE IMMEDIATE 'TRUNCATE TABLE TABLE_TEMP'; EXECUTE IMMEDIATE 'ALTER TABLE TABLE_A RENAME TO TABLE_B'; EXECUTE IMMEDIATE 'ALTER TABLE TABLE_TEMP RENAME TO TABLE_A'; EXECUTE IMMEDIATE 'ALTER TABLE TABLE_B RENAME TO TABLE_TEMP'; end;

2、创建查询表的同义词

CREATE OR REPLACE PACKAGE PKG_TEST IS PROCEDURE P_SEL(); END PKG_TEST; CREATE OR REPLACE PACKAGE BODY PKG_TEST IS PROCEDURE P_SEL() IS BEGIN --SELECT * FROM TABLE_A; SELECT * FROM SYN_TABLE_A;--create synonym syn_table_a for table_a END; END;

3、通过匿名块模拟业务顺序调用包内存储过程

BEGIN PKG_TEST.P_SEL(); pro_data_ex(); PKG_TEST.P_SEL(); END 空结果集 执行成功, 执行耗时62毫秒. 执行号:3926 影响了0条记录

注:参数PL_SQL_STRIP=4 需要开启

评论
后发表回复

作者

文章

阅读量

获赞

扫一扫
联系客服