2014-02-20 187 views
1

Oracle - 功能不能正常工作Oracle - 功能不能正常工作

所以我不知道我在做錯什麼。我已經呆了好幾個小時了,我真的很感激一些幫助。

所以基本上我有2個表,一個被稱爲student和它的學生名單與student_no作爲主鍵,另一臺名爲enrol基本上有該學生被錄取到程序列表。

所以我寫了一個函數,將登錄的學生的用戶名(在本例中爲student_no)與學生列表進行比較,並確保登錄的用戶是學生。然後它將student_noenrol表進行比較,以查找用戶註冊到的任何程序。因此,實質上當我SELECT * FROM yaser.enrol(表所有者是yaser)時,我應該只能從註冊列表中看到幾條記錄。相反,我得到的錯誤:failed to execute policy function

這裏是我的功能:

-- Create policy function to be called when 'ENROL' table is accessed 
create or replace function f_policy_enrol (schema in varchar2, tab in varchar2) 
-- Function will return a string that is used as a WHERE clause      
return varchar2 
as 
v_student_no  varchar2(10); 
is_student  number:=0; 
v_user   varchar2(100); 
out_string  varchar2(400) default '1=2 '; 

begin 
    -- get session user 
    v_user := lower(sys_context('userenv','session_user')); 

    -- Is the user a student? 
    begin 
    select student_no into v_student_no from student where lower(student_no) = v_user; 
    is_student:=1; 
    exception 
    when no_data_found then 
    v_student_no := 0; 
    end; 

    -- If it's a student, then they are only allowed to see their record only. 
    if is_student = 1 then 
    out_string := out_string||'or student_no = '||v_student_no||' '; 
    end if; 

    return out_string; 
end; 
/

這是我調用策略:

begin 
dbms_rls.add_policy('yaser', 
        'enrol', 
        'accesscontrol_enrol', 
        'yaser', 
        'f_policy_enrol', 
        policy_type => dbms_rls.context_sensitive); 
end; 
/

至於說before..I'm不知道我要去哪裏錯了。無論是在政策還是功能上。任何幫助將不勝感激!如果您有任何問題,我很高興回答,只要我有空工作一段時間!

在此先感謝!

亞瑟

回答

2

什麼student_no列的數據類型?列名意味着它是NUMBER。但是,您打電話lower並將其與會話用戶進行比較意味着這是一個VARCHAR2

假設student_noVARCHAR2,一個問題是您的謂詞缺少單引號圍繞值。如果v_student_no是,例如,「jcave」,你out_string

1=2 or student_no = jcave 

由於「jcave」沒有加引號,甲骨文假定所以它會在一個名爲jcave表中的列必須是一個標識符。找不到這樣的列,它會引發錯誤。如果您在字符串周圍放置單引號,則會有更多運氣。

out_string := out_string||'or student_no = '''||v_student_no||''' '; 

可能還有其他錯誤。您是否嘗試過手動調用該函數以查看它返回的內容?如果您在session_user設置爲「jcave」時手動調用該函數,則應該看到缺少單引號的結果。如果您複製並粘貼返回值並將其添加到SELECT聲明的末尾,您會立即看到該錯誤。您還可以查詢v$vpd_policy以查看已添加到特定SQL語句的特定策略謂詞(如果您想避免手動調用該函數) - 當您嘗試使用會話狀態調試VPD問題時,這非常有用你不能輕易重現。

+0

你說得對。它是一個'VARCHAR(10)'。儘管在應用修復程序後,它也給我提供了同樣的錯誤。我對Oracle非常陌生,老實說,我只是通過手動調用函數來了解你的意思。我做到了這一點,同樣的錯誤。還要別的嗎? :)感謝您的輸入堆。 –

+0

@YaserSleiman - 你是否在說,當你手動調用這個函數'從雙重'選擇f_policy_enrol(null,null),你會得到一個VPD相關的錯誤?這似乎不太可能。 –

+0

對不起!我誤解了。我以爲你的意思是'out_string:= out_string ||'或者student_no ='''|| v_student_no ||''''FROM yaser.enrol;'。恩,在這種情況下,我很抱歉,我不知道如何手動調用函數。 :( –