ADD_POLICY

该过程用于在某张表上添加一条安全策略

声明:

PROCEDURE ADD_POLICY(OBJECT_SCHEMA   IN VARCHAR2 := NULL,
                    OBJECT_NAME     IN VARCHAR2,
                    POLICY_NAME     IN VARCHAR2,
                    FUNCTION_SCHEMA IN VARCHAR2 := NULL,
                    POLICY_FUNCTION IN VARCHAR2,
                    STATEMENT_TYPES IN VARCHAR2 := NULL,
                    UPDATE_CHECK    IN BOOLEAN  := FALSE,
                    ENABLE          IN BOOLEAN  := TRUE,
                    STATIC_POLICY   IN BOOLEAN  := FALSE,
                    POLICY_TYPE     IN BINARY_INTEGER := NULL,
                    LONG_PREDICATE  IN BOOLEAN  := FALSE,
                    SEC_RELEVANT_COLS     IN VARCHAR2  := NULL,
                    SEC_RELEVANT_COLS_OPT IN BINARY_INTEGER := NULL);

结构:

参数 说明
OBJECT_SCHEMA OBJECT_NAME所在模式名(不指定则会使用当前用户名)
OBJECT_NAME 策略要添加到的表名
POLICY_NAME 策略名称
FUNCTION_SCHEMA POLICY_FUNCTION所在模式名(不指定则会使用当前用户名)
POLICY_FUNCTION 生成策略动态谓词的函数名称(可指定包名,如 PACK1.FUNC1)
STATEMENT_TYPES 哪种语句需检查该策略(支持SELECT、INSERT、UPDATE、DELETE,不指定等同于全部指定)
UPDATE_CHECK 默认FALSE,如果为TRUE,会检查新的元组是否满足动态谓词
ENABLE 默认为TRUE,表示策略创建后是否生效
STATIC_POLICY 默认FALSE(暂不支持)
POLICY_TYPE 默认NULL(暂不支持)
LONG_PREDICATE 默认FALSE(暂不支持)
SEC_RELEVANT_COLS 默认NULL(暂不支持)
SEC_RELEVANT_COLS_OPT 默认NULL(暂不支持)

注解

在添加策略时,允许指定的策略函数还未创建,但如果数据库在执行策略时函数仍未创建,将会报错。

策略函数的参数个数、参数类型、返回值类型需严格满足以下格式:

-- 参数 object_schema 应该传入策略所应用的表的模式名

-- 参数 object_name 应该传入策略所应用的表名

FUNCTION policy_function (object_schema IN VARCHAR2, object_name VARCHAR2) RETURN VARCHAR2

如果表上存在多个策略,最终的动态谓词是将每个策略函数返回值以 AND 逻辑进行连接。

如果策略函数返回 NULL 或空串,会按此策略不存在来处理。

如果 STATEMENT_TYPES 指定了 INSERT 或 UPDATE,同时 UPDATE_CHECK 为 TRUE,当新行不满足动态谓词条件,数据库会报错。

由于策略函数返回的谓词会添加到 WHERE 条件里,所以它不能直接包含 JOIN、ORDERY BY 、GROUP BY 等子句。

示例:

DROP TABLE TEST CASCADE;
CREATE TABLE TEST(ID INT, V1 INT);
INSERT INTO TEST VALUES(1, 123);
INSERT INTO TEST VALUES(2, 234);

DROP FUNCTION PTEST(OBJECT_SCHEMA VARHCAR2, OBJECT_NAME VARCHAR2);
CREATE OR REPLACE FUNCTION PTEST(OBJECT_SCHEMA VARCHAR2, OBJECT_NAME VARCHAR2)
RETURN VARCHAR2 IS
BEGIN
    --这里简单的返回一个条件
    RETURN 'ID != 1';

END;
/

SELECT * FROM TEST ORDER BY ID;
ID(int)      |V1(int)      |
--------------------------
1            |123          |
--------------------------
2            |234          |
总数目:2


EXEC DBMS_RLS.ADD_POLICY(
      object_name        => 'TEST',
      policy_name        => 'POLICY_1',
      policy_function    => 'PTEST',
      statement_types    => 'INSERT,UPDATE,DELETE,SELECT');


SELECT * FROM TEST ORDER BY ID;
ID(int)      |V1(int)      |
--------------------------
2            |234          |
总数目:1


EXEC DBMS_RLS.ENABLE_POLICY(
      object_name        => 'TEST',
      policy_name        => 'POLICY_1',
      enable             => 'FALSE');


SELECT * FROM TEST ORDER BY ID;
ID(int)      |V1(int)      |
--------------------------
1            |123          |
--------------------------
2            |234          |
总数目:2


EXEC DBMS_RLS.DROP_POLICY(
      object_name        => 'TEST',
      policy_name        => 'POLICY_1');