Oracle PL/SQL 包依赖管理详解
Oracle PL/SQL 包依赖管理详解
适用版本:Oracle Database 10g / 11g / 12c / 19c / 23ai 文档版本:v1.0 / 2026-07
1. 概述
PL/SQL 包依赖管理保证代码稳定性[1]:
2. 依赖类型
2.1 直接
- A 调用 B
- A 依赖 B
2.2 间接
- A 调用 B,B 调用 C
- A 间接依赖 C
2.3 本地
- 同 Schema
- 远程(DB Link)
3. 查看
3.1 依赖
SELECT name, type, referenced_name, referenced_type
FROM user_dependencies
WHERE name = 'EMP_PKG';
-- 反向
SELECT name, type
FROM user_dependencies
WHERE referenced_name = 'EMPLOYEES';
3.2 编译错误
SELECT object_name, object_type, status
FROM user_objects
WHERE status = 'INVALID';
-- 详细
SELECT name, type, line, position, text
FROM user_errors;
3.3 对象
SELECT object_name, object_type, status, last_ddl_time
FROM user_objects
WHERE object_type IN ('PACKAGE', 'PACKAGE BODY', 'PROCEDURE', 'FUNCTION')
ORDER BY object_name;
4. 失效原因
4.1 依赖对象变更
- 表结构变更
- 视图重定义
- 类型变更
- 包重编译
4.2 权限
- 权限撤销
- 角色变更
4.3 远程
- DB Link 失效
- 远程对象变更
5. 重新编译
5.1 手动
ALTER PACKAGE emp_pkg COMPILE;
ALTER PACKAGE emp_pkg COMPILE SPECIFICATION;
ALTER PACKAGE emp_pkg COMPILE BODY;
ALTER PROCEDURE my_proc COMPILE;
ALTER FUNCTION my_func COMPILE;
ALTER TRIGGER my_trig COMPILE;
ALTER VIEW my_view COMPILE;
5.2 批量
-- Schema
@?/rdbms/admin/utlrp.sql
-- 或
EXEC UTL_RECOMP.RECOMP_SERIAL('SCOTT');
EXEC UTL_RECOMP.RECOMP_PARALLEL(4, 'SCOTT');
5.3 自动
ALTER SYSTEM SET plsql_optimize_level = 2;
-- 自动重编译
6. 编译参数
6.1 PLSQL_CCFLAGS
ALTER SESSION SET PLSQL_CCFLAGS = 'DEBUG:TRUE,VERSION:2';
6.2 PLSQL_OPTIMIZE_LEVEL
ALTER SESSION SET PLSQL_OPTIMIZE_LEVEL = 2; -- 0-3
6.3 PLSQL_CODE_TYPE
ALTER SESSION SET PLSQL_CODE_TYPE = NATIVE; -- INTERPRETED / NATIVE
6.4 PLSQL_WARNINGS
ALTER SESSION SET PLSQL_WARNINGS = 'ENABLE:ALL';
7. 条件编译
7.1 基本
CREATE OR REPLACE PROCEDURE my_proc IS
BEGIN
$IF $$DEBUG $THEN
DBMS_OUTPUT.PUT_LINE('Debug mode');
$END
$IF $$VERSION > 1 $THEN
-- 新版本代码
$ELSE
-- 旧版本代码
$END
END;
/
7.2 设置
ALTER SESSION SET PLSQL_CCFLAGS = 'DEBUG:TRUE,VERSION:2';
7.3 查看
SELECT name, value
FROM user_plsql_object_settings
WHERE name = 'MY_PROC';
8. 循环依赖
8.1 问题
- A 依赖 B
- B 依赖 A
- 无法编译
8.2 解决
- 重构
- 提取公共到 C
- 接口
- 动态调用
8.3 动态调用
-- A 调用 B(动态)
EXECUTE IMMEDIATE 'BEGIN b_pkg.proc(:1); END;' USING p_arg;
-- 避免静态依赖
9. 版本管理
9.1 编译时间
SELECT object_name, object_type, created, last_ddl_time, status
FROM user_objects
WHERE object_type = 'PACKAGE BODY'
ORDER BY last_ddl_time DESC;
9.2 源代码
SELECT name, type, line, text
FROM user_source
WHERE name = 'EMP_PKG'
ORDER BY line;
9.3 版本控制
- 脚本文件
- Git
- Flyway / Liquibase
详细见:Oracle SQL 开发规范详解。
10. 重编译脚本
10.1 自动
BEGIN
FOR rec IN (
SELECT object_name, object_type
FROM user_objects
WHERE status = 'INVALID'
AND object_type IN ('PACKAGE', 'PACKAGE BODY', 'PROCEDURE', 'FUNCTION', 'TRIGGER', 'VIEW')
) LOOP
BEGIN
EXECUTE IMMEDIATE 'ALTER ' || rec.object_type || ' ' || rec.object_name || ' COMPILE';
DBMS_OUTPUT.PUT_LINE('Compiled: ' || rec.object_name);
EXCEPTION
WHEN OTHERS THEN
DBMS_OUTPUT.PUT_LINE('Failed: ' || rec.object_name || ' - ' || SQLERRM);
END;
END LOOP;
END;
/
10.2 依赖顺序
-- 按依赖顺序
-- 1. 类型
-- 2. 表
-- 3. 序列
-- 4. 视图
-- 5. 包规范
-- 6. 包主体
-- 7. 过程/函数
-- 8. 触发器
11. 监控
11.1 失效对象
SELECT object_name, object_type, status
FROM user_objects
WHERE status = 'INVALID'
ORDER BY object_type, object_name;
11.2 警告
SELECT name, type, sequence, line, position, text
FROM user_errors
ORDER BY name, sequence;
11.3 编译时间
SELECT object_name, object_type, last_ddl_time
FROM user_objects
WHERE last_ddl_time > SYSDATE - 1
ORDER BY last_ddl_time DESC;
12. 应用场景
12.1 部署
- 脚本顺序
- 依赖管理
- 编译
12.2 变更
- 表结构变更
- 重编译依赖
- 测试
12.3 升级
- 版本
- 兼容
- 迁移
13. 常见坑与排错
13.1 失效
- 依赖变更
- 自动重编译
- 手动
13.2 编译错误
- 语法
- 类型
- 权限
13.3 循环
- 重构
- 动态调用
14. 最佳实践
- 依赖顺序:编译
- utlrp.sql:批量
- 监控失效:及时
- 条件编译:版本
- 避免循环:重构
- 动态调用:解耦
- 版本控制:管理
- 测试:验证
- 文档:依赖
- 自动化:脚本
15. 参考资料
[1] Oracle Database PL/SQL Language Reference 19c, “Dependencies” https://docs.oracle.com/en/database/oracle/oracle-database/19/lnpls/plsql-packages.html