1

如何修改函数以便用户 (HR1) 可以查看 CTL_UPD_USER 为 VPD_CLERK1 或 VPD_CLERK2 的行?

我对 Oracle 和 pl/sql 很陌生。

RETURN VARCHAR2 AS 
   con VARCHAR2 (200); 
BEGIN
IF USER ='HR1' THEN
   con := 'CTL_UPD_USER=' ||'''VPD_CLERK1''';
else 
   con:= 'CTL_UPD_USER=USER'; 
end if;
RETURN (con); 
END;

我尝试了 OR 的各种用法并得到一个编译错误:pl/sql 语句被忽略,表达式类型错误:

Con := 'CTL_UPD_USER=' ||'''VPD_CLERK1''' OR 
'CTL_UPD_USER='||'''VPD_CLERK3''';

工作代码:

CREATE TABLE CUSTOMERS (
           SALES_REP_ID NUMBER(4),
           CUSTOMER_ID NUMBER(8),
           CTL_UPD_DTTM DATE,
           CTL_UPD_USER VARCHAR2(30),
           CTL_REC_STAT CHAR(1),
           primary key (sales_rep_id, customer_id)
);

insert into customers values (1000, 90000,NULL, 'VPD_CLERK1','1');
insert into customers values (1000, 90001,NULL, 'VPD_CLERK1','2');
insert into customers values (1000, 90002,NULL, 'VPD_CLERK2','3');
insert into customers values (1000, 90003,NULL, 'VPD_CLERK2','4');
insert into customers values (1000, 90004,NULL, 'VPD_CLERK3','5');

CREATE OR REPLACE FUNCTION 
    DBSEC_ROW_OWNER_WHERE( 
          P_SCHEMA_NAME IN VARCHAR2, 
          P_OBJECT_NAME IN VARCHAR2) 
RETURN VARCHAR2 AS 
  con VARCHAR2 (200); 
BEGIN
IF USER ='HR1' THEN
  con := 'CTL_UPD_USER=' ||'''VPD_CLERK1''';
else 
  con:= 'CTL_UPD_USER=USER'; 
end if;
RETURN (con); 
END;

exec dbms_rls.add_policy(object_schema =>'DBSEC',object_name =>
'CUSTOMERS',policy_name => 'dbsec_row_onwer_policy', function_schema => 
'SYS',
 policy_function =>'DBSEC_ROW_OWNER_WHERE', enable => true);

我希望能够以 HR1 身份登录并查看 CTL_UPD_USER 为 VPD_CLERK1 或 VPD_CLERK2 或用户为 HR1 的行。

4

1 回答 1

1

IN 子句怎么样?

SQL> CREATE TABLE scott.CUSTOMERS (
  2             SALES_REP_ID NUMBER(4),
  3             CUSTOMER_ID NUMBER(8),
  4             CTL_UPD_DTTM DATE,
  5             CTL_UPD_USER VARCHAR2(30),
  6             CTL_REC_STAT CHAR(1),
  7             primary key (sales_rep_id, customer_id)
  8  );

Table created.

SQL>
SQL> grant select on scott.CUSTOMERS to hr;

Grant succeeded.

SQL>
SQL> insert into scott.customers values (1000, 90000,NULL, 'VPD_CLERK1','1');

1 row created.

SQL> insert into scott.customers values (1000, 90001,NULL, 'VPD_CLERK1','2');

1 row created.

SQL> insert into scott.customers values (1000, 90002,NULL, 'VPD_CLERK2','3');

1 row created.

SQL> insert into scott.customers values (1000, 90003,NULL, 'VPD_CLERK2','4');

1 row created.

SQL> insert into scott.customers values (1000, 90004,NULL, 'VPD_CLERK3','5');

1 row created.

SQL>
SQL> CREATE OR REPLACE FUNCTION
  2      scott.DBSEC_ROW_OWNER_WHERE(
  3            P_SCHEMA_NAME IN VARCHAR2,
  4            P_OBJECT_NAME IN VARCHAR2)
  5  RETURN VARCHAR2 AS
  6    con VARCHAR2 (200);
  7  BEGIN
  8  IF USER ='HR' THEN
  9    con := 'CTL_UPD_USER in (' ||'''VPD_CLERK1'',''VPD_CLERK2'')';
 10  else
 11    con:= 'CTL_UPD_USER=USER';
 12  end if;
 13  RETURN (con);
 14  END;
 15  /

Function created.

SQL>
SQL> begin
  2    dbms_rls.add_policy(
  3      object_schema =>'SCOTT',
  4      object_name =>'CUSTOMERS',
  5      policy_name => 'dbsec_row_onwer_policy',
  6      function_schema => 'SCOTT',
  7      policy_function =>'DBSEC_ROW_OWNER_WHERE',
  8      enable => true);
  9  end;
 10  /

PL/SQL procedure successfully completed.

SQL>
SQL> conn hr/hr
Connected.

SQL>
SQL> select * from scott.customers;

SALES_REP_ID CUSTOMER_ID CTL_UPD_D CTL_UPD_USER                   C
------------ ----------- --------- ------------------------------ -
        1000       90000           VPD_CLERK1                     1
        1000       90001           VPD_CLERK1                     2
        1000       90002           VPD_CLERK2                     3
        1000       90003           VPD_CLERK2                     4

4 rows selected.
于 2019-11-10T08:49:30.603 回答