实现VPD谓词函数 - ORA-28110:策略函数或包有错误

时间:2016-04-04 22:20:31

标签: oracle plsql

我正在尝试在表上实现谓词函数。包和谓词函数编译没有问题,但是当我在表上选择时,我收到此错误:

SELECT * FROM MSGG_GUIDES;

ORA-28110: policy function or package VPD674.MSGG_SECURITY_POLICY has error

这是我定义的功能。下面的代码是函数所属的包体的片段。我的最终目标是让这个函数为你在if语句中看到的4个表定义一个策略。

  function MSGG_SECURITY_POLICY (schema_in varchar2, NAME_IN varchar2)
    return varchar2 
    IS 
    where_stmt varchar2(5000);
    BEGIN

      if schema_in='VPD674' and NAME_IN='MSGG_GUIDES' THEN
        where_stmt := 'PERSON_ID = MSGG_SESSION.get_user_id';

      elsif schema_in='VPD674' and NAME_IN='MSGG_ORDERS' THEN
        where_stmt := 'ORDERING_PERSON = MSGG_SESSION.get_user_id';

      elsif schema_in='VPD674' and NAME_IN='MSGG_SIGHTING_REPORTS' THEN
        where_stmt := 'PERSON_ID = MSGG_SESSION.get_user_id';

      elsif schema_in='VPD674' and NAME_IN='MSGG_TRIP_HISTORY' THEN
        where_stmt := 'GUIDE_ID = MSGG_SESSION.get_user_id';

      end if;

    return (where_stmt);

以下是它如何应用于相关表格(我正在选择的那个)。

BEGIN
DBMS_RLS.ADD_POLICY(
  object_schema => 'VPD674',
  object_name => 'MSGG_GUIDES',
  policy_name => 'MSGG_SECURITY_POLICY1',
  function_schema => 'VPD674',
  policy_function => 'MSGG_SECURITY_POLICY',
  statement_types => 'SELECT');

END;
/

关于为什么选择错误的任何想法?该函数编译没有问题。包,函数或策略上的“show errors”命令返回“no errors”。我尝试了一个不使用get_user_id函数作为故障排除步骤的函数的硬编码版本,但我仍然收到相同的错误。我还尝试在包外部创建函数并将其应用于策略,但收到了同样的错误。

完整披露,以下是整个包规范和正文创建脚本。您将看到我提到的硬编码功能版本(MSGG_SECURITY_POLICY_G)。

CREATE OR REPLACE PACKAGE MSGG_SESSION AS 
    PROCEDURE authenticate (current_username varchar2, current_password varchar2);  
    function get_user_id 
  RETURN NUMBER;
  function MSGG_SECURITY_POLICY (schema_in varchar2, NAME_IN varchar2)
  RETURN VARCHAR2;
  function MSGG_SECURITY_POLICY_G (schema_var IN VARCHAR2,  table_var  IN VARCHAR2)
  RETURN VARCHAR2;
end MSGG_SESSION;
/

CREATE OR REPLACE PACKAGE BODY MSGG_SESSION AS 
    person_id_var NUMBER;

  function get_user_id 
        return NUMBER IS BEGIN

            return(person_id_var);

        end get_user_id;

    PROCEDURE authenticate (current_username varchar2, current_password varchar2) IS BEGIN

            SELECT personID 
      INTO person_id_var
            FROM MSGG_USER
            WHERE (current_username=username and current_password=password);

      DBMS_OUTPUT.put_line(person_id_var);

        END authenticate;   

  function MSGG_SECURITY_POLICY (schema_in varchar2, NAME_IN varchar2)
    return varchar2 
    IS 
    where_stmt varchar2(5000);
    BEGIN

      if schema_in='VPD674' and NAME_IN='MSGG_GUIDES' THEN
        where_stmt := 'PERSON_ID = MSGG_SESSION.get_user_id';

      elsif schema_in='VPD674' and NAME_IN='MSGG_ORDERS' THEN
        where_stmt := 'ORDERING_PERSON = MSGG_SESSION.get_user_id';

      elsif schema_in='VPD674' and NAME_IN='MSGG_SIGHTING_REPORTS' THEN
        where_stmt := 'PERSON_ID = MSGG_SESSION.get_user_id';

      elsif schema_in='VPD674' and NAME_IN='MSGG_TRIP_HISTORY' THEN
        where_stmt := 'GUIDE_ID = MSGG_SESSION.get_user_id';

      end if;

    return (where_stmt); 

    end MSGG_SECURITY_POLICY;

FUNCTION MSGG_SECURITY_POLICY_G( 
  schema_var IN VARCHAR2,
  table_var  IN VARCHAR2
 )
 RETURN VARCHAR2
 IS
  return_val VARCHAR2 (400);
 BEGIN
  return_val := 'PERSON_ID = ''14''';
  RETURN return_val;
 END MSGG_SECURITY_POLICY_G;

end MSGG_SESSION;

/

1 个答案:

答案 0 :(得分:1)

嗯,对于下一个出现的人,我能够弄清楚这一点。我构建ADD_POLICY的方式不正确。我需要在policy_function参数中包含包含该函数的包名称。这是更正后的版本。您将看到我在函数名称之前添加了MSGG_SESSION。

BEGIN
DBMS_RLS.ADD_POLICY(
  object_schema => 'VPD674',
  object_name => 'MSGG_GUIDES',
  policy_name => 'MSGG_SECURITY_POLICY1',
  function_schema => 'VPD674',
  policy_function => 'MSGG_SESSION.MSGG_SECURITY_POLICY',
  statement_types => 'SELECT');
END;
/