2016-04-04 38 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; 
/

任何有關爲什麼選擇錯誤的想法?該函數編譯沒有問題。程序包,函數或策略中的「顯示錯誤」命令返回「無錯誤」。我試圖使用不使用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; 
/