2013-07-24 51 views
0

由於表變異,以下觸發器不起作用,因爲我相信觸發器中的SQL語句不能對變異表執行,但是因爲我不在11g上,所以我不能創建複合觸發器。我已經在聲明部分嘗試了包括PRAGMA AUTONOMOUS TRANSACTION;,但是這不會被編譯。任何人都可以爲我提供最佳解決方案嗎?Oracle觸發器創建 - 表正在變異;觸發器可能無法讀取或修改它

create or replace 
trigger fb_pers_id_check2_tr 
    --after insert on ifsapp.person_info_tab 
    before insert on ifsapp.person_info_tab  
for each row 
begin 
    declare 
-- pragma autonomous_transaction; 
    v_pid_ person_info_tab.person_id%type; 
    format_name_ person_info_tab.name%type; 
    begin 

    v_pid_ := :new.person_id; 

    select regexp_replace(upper(:new.name), '\W') 
    into format_name_ 
    from ifsapp.person_info_tab 
    where person_id = v_pid_; 

    if length(v_pid_) < 3 and (length(format_name_) < 21 and v_pid_ <> format_name_) then 
    raise_application_error(-20001, 'Person ID: ' || v_pid_ || 'is not valid, please enter a valid  Person ID, e.g. "' || format_name_ || '".'); 
    end if; 
end; 
end fb_pers_id_check2_tr; 

N.B.用簡單的英語,此觸發器旨在阻止用戶設置長度小於3個字符的人員ID,如果長度小於21個字符,則不會與變量「format_name_」相等。

+0

那麼,爲什麼這不是一個事先插入觸發器,而不是檢查'length(:new.person_id)',並與格式化的':new.name'進行比較?你爲什麼需要看錶格版本? –

+0

我編輯了問題中的代碼以反映您的建議,但是當這樣做時它會返回錯誤'找不到數據'。 – pwl

+0

如果您插入一個新行,它將不會在表中找到。 –

回答

2

Oracle不允許行觸發器讀取或修改定義觸發器的表。但是,如果PERSON_ID是PERSON_INFO_TAB上的PRIMARY或UNIQUE鍵(這似乎是在單例SELECT中使用它的情況),您並不需要閱讀表格 - 只需在適當的位置使用OLD或NEW值:

create or replace trigger fb_pers_id_check2_tr 
    before insert on ifsapp.person_info_tab 
    for each row 
declare 
    v_pid_ person_info_tab.person_id%type; 
    format_name_ person_info_tab.name%type; 
begin 
    v_pid_ := :new.person_id; 

    format_name_ := REGEXP_REPLACE(UPPER(:new.name), '\W');  

    if length(v_pid_) < 3 and 
    length(format_name_) < 21 and 
    v_pid_ <> format_name_ 
    then 
    raise_application_error(-20001, 'Person ID: ' || v_pid_ || 
          ' is not valid, please enter a valid' || 
          ' Person ID, e.g. "' || format_name_ || '".'); 
    end if; 
end fb_pers_id_check2_tr; 

下面的代碼是檢查名稱的新值(我認爲這是正確的,因爲它似乎驗證輸入),但如果目的是檢查舊值它是簡單的改變:新作:REGEXP_REPLACE調用中的OLD。

分享和享受。

+0

我已經將此更改爲BEFORE INSERT觸發器,以便將OP的更改與問題匹配。我相信答案仍然有效 - 引用歐比旺,「使用:新值,盧克!」。分享並享受。 –

+0

謝謝大家的幫助。 – pwl