Oracle如何限制非法调用包中过程
假如我有一个包P_A,其中封装了重要过程DO_A。 
另有一个包P_B需要调用P_A.DO_A实现重要商业逻辑。 
我想只授权给包P_B调用,认为其他途径调用P_A.DO_A都是非法的! 
下面根据PL/SQL开发大师[福伊尔斯坦]提供的方法实现如下:
CREATE OR REPLACE PACKAGE p_a IS 
PROCEDURE do_a; 
END p_a; 
/
CREATE OR REPLACE PACKAGE BODY p_a IS 
PROCEDURE do_a IS 
BEGIN 
dbms_output.put_line(‘DO_A FROM P_A’); 
END do_a; 
END p_a; 
/
CREATE OR REPLACE PACKAGE P_B 
IS 
PROCEDURE DO_B; 
END P_B; 
/
CREATE OR REPLACE PACKAGE BODY P_B 
IS 
PROCEDURE DO_B 
IS 
BEGIN 
P_A.DO_A; 
END DO_B; 
END P_B; 
/
BEGIN 
P_A.DO_A; –被认为是非法调用 
P_B.DO_B; –唯一合法调用 
END; 
/
–如何限制只有P_B可调用P_A.DO_A? 
–12c以前,我们使用DBMS_UTILITY .FORMAT_CALL_STACK 
–编写自定义函数: 
CREATE OR REPLACE FUNCTION i_was_called_by (program_in IN VARCHAR2) 
RETURN BOOLEAN 
IS 
c_stack CONSTANT VARCHAR2 (32767) 
:= DBMS_UTILITY.format_call_stack; 
BEGIN 
RETURN INSTR (SUBSTR (c_stack, 
INSTR (c_stack, 
CHR (10),1,5)+ 1, 
INSTR (c_stack, CHR (10),1,6) 
- INSTR (c_stack,CHR (10),1,5) 
+ 1), 
program_in) > 0; 
END;
—– PL/SQL Call Stack —– 
object line object 
handle number name 
000007FF50456200 4 function SCOTT.I_WAS_CALLED_BY 
000007FF504ADD28 4 package body SCOTT.P_A 
000007FF50439820 2 anonymous block
–修改P_A.DO_A过程: 
PROCEDURE DO_A 
IS 
BEGIN 
IF i_was_called_by (‘P_B’) 
THEN 
dbms_output.put_line(‘DO_A FROM P_A’); 
ELSE 
RAISE_APPLICATION_ERROR(-20209, ‘非法调用!’); 
END IF; 
END; 
/
–再次调用发现 
BEGIN 
* 
第 1 行出现错误: 
ORA-20209: 非法调用! 
ORA-06512: 在 “SCOTT.P_A”, line 7 
ORA-06512: 在 line 2
–12c以后,我们使用包的ACCESSIBLE BY条件 
–修改包P_A说明部分 
CREATE OR REPLACE PACKAGE p_a 
ACCESSIBLE BY(P_B) 
IS 
PROCEDURE do_a; 
END p_a; 
/

