ORACLE 包中的常量 与 ORA-04068 错误
oracle 包中的常量(包括全局和私有)与 ORA-04068 错误 (一)中展示了包中常量带来的问题,这里我们
改变常量定义位置,来解决这类问题。我们新增一个常量包:PG_CONSTANT。将所有包中的常量都定义在此包
中,PG_CONSTANT 只有包头,不需要包头。定义如下:
CREATE OR REPLACE PACKAGE PG_CONSTANT AS
-- 常量包
-- PG_COMMON 常量
C_CODE_ERROR CONSTANT VARCHAR2(10) := 'ERROR';
C_CODE_SUCCESS CONSTANT VARCHAR2(10) := 'SUCCESS';
-- PG_TO 常量
C_TO_STATUS_OPEN CONSTANT VARCHAR2(10) := 'OPEN';
C_TO_STATUS_CLOSE CONSTANT VARCHAR2(10) := 'CLOSE';
C_TO_STATUS_CANCEL CONSTANT VARCHAR2(10) := 'CANCEL';
END PG_CONSTANT;
CREATE OR REPLACE PACKAGE PG_CONSTANT AS
-- 常量包
-- PG_COMMON 常量
C_CODE_ERROR CONSTANT VARCHAR2(10) := 'ERROR';
C_CODE_SUCCESS CONSTANT VARCHAR2(10) := 'SUCCESS';
-- PG_TO 常量
C_TO_STATUS_OPEN CONSTANT VARCHAR2(10) := 'OPEN';
C_TO_STATUS_CLOSE CONSTANT VARCHAR2(10) := 'CLOSE';
C_TO_STATUS_CANCEL CONSTANT VARCHAR2(10) := 'CANCEL';
END PG_CONSTANT;
然后去掉其它包中的所有常量,并改用常量包中的常量,
PG_COMMON包头接口不变,包体如下:
CREATE OR REPLACE PACKAGE BODY PG_COMMON AS
FUNCTION SP_IS_EXIST_TO(I_TO NUMBER) RETURN BOOLEAN IS
V_FLAG BOOLEAN := FALSE;
V_COUNT NUMBER := 0;
BEGIN
-- 不为空 返回 TRUE
IF I_TO IS NOT NULL THEN
SELECT COUNT(1) INTO V_COUNT FROM t_* WHERE t_*.TO = I_TO;
END IF;
IF V_COUNT > 0 THEN
V_FLAG := TRUE;
END IF;
RETURN V_FLAG;
END SP_IS_EXIST_TO;
END PG_COMMON;
PG_TO包也是如此,包头不变,包体如下(所有常量,都用常量包的数据):
CREATE OR REPLACE PACKAGE BODY PG_TO AS
PROCEDURE SP_GET_TO_STATUS(I_TO IN NUMBER,
O_TO_STATUS OUT VARCHAR2,
O_CODE OUT VARCHAR2) IS
V_FLAG BOOLEAN := FALSE;
BEGIN
-- 默认为失败
O_CODE := PG_CONSTANT.C_CODE_ERROR;
V_FLAG := PG_COMMON.SP_IS_EXIST_TO(I_TO => I_TO);
IF V_FLAG = TRUE THEN
-- 去掉默认,更为具体实现
SELECT t_*.status
INTO O_TO_STATUS
FROM t_*
WHERE t_*.TO = I_TO;
ELSE
-- TO 号不存在
O_CODE := PG_CONSTANT.C_CODE_ERROR;
RETURN;
END IF;
-- 成功
O_CODE := PG_CONSTANT.C_CODE_SUCCESS;
EXCEPTION
WHEN OTHERS THEN
RAISE;
END SP_GET_TO_STATUS;
END PG_TO;
先对所有包重新编译。测试如下,
SQL> set serveroutput on ;
SQL>
SQL> DECLARE
2 V_TO_NO VARCHAR2(10);
3 V_CODE VARCHAR2(10);
4 V_TO_STATUS VARCHAR2(10);
5 BEGIN
6 V_TO_NO := 7369;
7 PG_TO.SP_GET_TO_STATUS(I_TO => V_TO_NO,
8 O_TO_STATUS => V_TO_STATUS,
9 O_CODE => V_CODE);
10
11 IF V_CODE = Pg_Constant.C_CODE_ERROR THEN -- 常量包
12 DBMS_OUTPUT.PUT_LINE(V_CODE);
13 ELSE
14 DBMS_OUTPUT.PUT_LINE('TO STATUS:'||V_TO_STATUS);
15 END IF;
16 END ;
17 /
TO STATUS:OPEN
这时,你可以放心的改PG_COMMON,PG_TO包中的所有内容,即在 jboss运行时也可以调整你的过程,而不会出现:
ORA-04068: 已丢弃程序包 的当前状态
ORA-04061: package "SCOTT.PG_TO" 的当前状态失效
这种方式也有一个小小的不足,就是不能随意改动 PG_CONSTANT 包,但比起我们不能改动其它业务包,这种解决是非常满意的了。
参考资料:
http://blog.csdn.net/kechengtan/article/details/6268450
http://blog.csdn.net/qshpeng/article/details/6424375