有没有办法在 PL/SQL 中创建 'modules'?

Is there a way to create 'modules' in PL/SQL?

我正在研究创建模块(或类似概念)的方法,许多 packages/functions/procedures 将居住在其中,但我只公开了一些外观 API。

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

我正在考虑使用 db schemata 作为 'module' 系统,但 AFAIK 它不限制访问。

有什么想法吗?

创建一个用户,用那个用户编译所有packages/functions/procedures。创建第二个用户并授予少数 packages/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 不在包规范中,因此它仅在同一包中可见。

如果您希望控制访问权限,但不一定要控制可见性,请使用 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;

通过 public API

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

结果:私人问候API!

测试直接访问私有API

BEGIN
  private_api.p2_pvt;
END;
/

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