有没有办法创建'模块'在PL / SQL?

时间:2017-04-28 15:03:50

标签: oracle plsql modularity

我正在研究创建模块(或类似概念)的方法,其中包含许多软件包/函数/过程,但我只公开了一些Facade API。

这样做的主要原因是我想限制对任何非API方法的任何直接访问,以促进解耦和模块化。

我在考虑使用db schemata作为'模块'系统,但AFAIK并没有限制访问。

有什么想法吗?

2 个答案:

答案 0 :(得分:2)

创建用户,使用该用户编译所有包/函数/过程。创建第二个用户并授予您想要提供的几个软件包/ etc的访问权限,并且只允许通过该用户访问(而不是直接通过所有者)。

类似的东西:

CREATE USER package_owner IDENTIFIED BY password ACCOUNT LOCK;
REVOKE CREATE SESSION FROM package_owner;

CREATE PACKAGE package_owner.your_api
  PROCEDURE your_api_procedure;
END;
/

CREATE PACKAGE BODY package_owner.your_api
  PROCEDURE your_api_procedure IS BEGIN NULL; END;

  PROCEDURE private_procedure IS BEGIN NULL; END;
END;
/

CREATE PACKAGE package_owner.your_hidden_package
  PROCEDURE your_hidden_procedure;
END;
/

CREATE PACKAGE BODY package_owner.your_hidden_package
  PROCEDURE your_hidden_procedure IS BEGIN NULL; END;
END;
/

CREATE USER access_point IDENTIFIED BY password ACCOUNT UNLOCK;
GRANT CREATE SESSION TO access_point;
GRANT EXECUTE ON package_owner.your_api TO access_point;

现在您可以连接到用户access_point并执行your_api包,但无法执行your_hidden_package

另请注意,虽然your_api可以从access_point用户执行,但private_procedure不在包规范中,因此只能在同一个包中显示。

答案 1 :(得分:2)

如果您希望控制访问权限,但不一定是可见性,请使用Oracle 12.1中的PL / SQL白名单功能。

如,

设置

CREATE OR REPLACE PACKAGE public_api AS
  PROCEDURE p1_pub;
END;
/

CREATE OR REPLACE PACKAGE private_api 
  ACCESSIBLE BY (PACKAGE public_api)  -- This is the key part of the feature
AS
  PROCEDURE p2_pvt;
END private_api;
/ 

CREATE OR REPLACE PACKAGE BODY public_api AS
  PROCEDURE p1_pub IS
  BEGIN
    private_api.p2_pvt;
  END;
END public_api;

CREATE OR REPLACE PACKAGE BODY private_api AS
  PROCEDURE p2_pvt IS
  BEGIN
    DBMS_OUTPUT.PUT_LINE('Hello from private API!');
  END;
END private_api;

通过公共API

测试访问权限
BEGIN
  public_api.p1_pub;
END;
/

结果:来自私有API的Hello!

测试对私有API的直接访问

BEGIN
  private_api.p2_pvt;
END;
/

结果: PLS-00904:访问对象PRIVATE_API的权限不足