2016-04-04 27 views
2

表に述語関数を実装しようとしています。パッケージと述語関数は問題なくコンパイルされますが、テーブルを選択するとこのエラーが発生します。VPD述語関数の実装 - ORA-28110:ポリシー関数またはパッケージにエラーがあります

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

これから来る人のために、私はこれを理解することができました。 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; 
/
関連する問題