ACCESSIBLE BY 子句仅适用于包(CREATE PACKAGE/BODY),不支持独立过程或函数;必须在包头声明,只接受同schema包名或类型名,用于编译期限定包内子程序的调用来源,不影响运行时权限控制。

ACCESSIBLE BY 只能用于包,不能用于独立过程
Oracle 的 ACCESSIBLE BY 子句是 12c 引入的访问控制机制,但它**不支持独立存储过程或函数**。如果你对一个单独创建的 CREATE PROCEDURE my_proc 尝试加 ACCESSIBLE BY (package_name),会直接报 ORA-00922: missing or invalid option。它只被允许出现在 CREATE PACKAGE 或 CREATE PACKAGE BODY 的声明中,且仅作用于该包内定义的子程序(过程、函数、游标、变量等)。
必须在包头声明 ACCESSIBLE BY,且只接受包名或类型名
你不能在包体里写 ACCESSIBLE BY,也不能用用户名、角色、同义词或字符串字面量。合法写法只有两种:
-
ACCESSIBLE BY (my_pkg)—— 允许同 schema 下另一个包my_pkg访问本包中带该子句的成员 -
ACCESSIBLE BY (my_type)—— 允许同 schema 下一个对象类型(CREATE TYPE)访问
常见错误包括:ACCESSIBLE BY (scott.my_pkg)(跨 schema 不允许)、ACCESSIBLE BY ('MY_PKG')(引号导致语法错误)、ACCESSIBLE BY (app_role)(角色不被接受)。
被限制的过程仍需 EXECUTE 权限才能调用
ACCESSIBLE BY 是编译期检查,不是运行时权限控制。即使你把 proc_a 声明为 ACCESSIBLE BY (helper_pkg),外部用户依然可以执行 EXEC hr.my_pkg.proc_a——只要他有 EXECUTE ON hr.my_pkg 权限。真正起作用的是:当 helper_pkg 内部代码尝试调用 my_pkg.proc_a 时,编译器会验证 my_pkg 是否在 proc_a 的 ACCESSIBLE BY 列表中;若不在,CREATE PACKAGE BODY helper_pkg 直接失败,报 PLS-00904: insufficient privilege to access object。
典型误用:以为它能替代 GRANT EXECUTE
很多开发者想用 ACCESSIBLE BY 来“隐藏”过程,避免被其他应用误调。但这是错的。它不阻止任何运行时调用,也不影响权限模型。你依然要显式执行 GRANT EXECUTE ON hr.my_pkg TO app_user;如果没授,app_user 调用会报 PLS-00201 或 ORA-00942,跟有没有 ACCESSIBLE BY 完全无关。它的唯一价值是让包之间调用关系更清晰、更强制——比如防止业务包意外依赖底层工具包的内部过程,这种约束只在开发阶段生效。


















