2012-05-23 41 views
0

有什麼辦法讓oracle通過約束來檢查表的其他記錄嗎?Oracle:涉及其他記錄的複雜約束

讓我們舉個例子:

我有一個表叫ENI_TRASC_VOCI_PWR_FATT,我想這有tvp_regione不爲空每條記錄具有tvp_regione = NULL類似的記載。

對於類似的記錄,我需要檢查它在TVP_CODICE_ASSOGGETAMEN柱上具有相同的值。

+0

所以你有雙記錄?一個null,一個不null? – APC

+0

由於Oracle對CHECK約束條件的限制,我認爲您將不得不使用觸發器(可能是BEFORE INSERT或UPDATE ON ENI_TRAC_VOCI_PWR_FATT)來執行此驗證。 –

+0

@APC:是的,正確 – Revious

回答

1

根據Oracle docs

的檢查約束條件不能包含以下 結構:
子查詢和標量子查詢表達式

所以你可能不得不使用觸發器相反:

create or replace trigger trg 
before insert or update on ENI_TRASC_VOCI_PWR_FATT 
for each row 

begin 
    -- do whatever queries you need - I didn't understand what you want 
    if <some condition> then 
    raise_application_error(-20000,'no good'); 
    end if; 
end; 

但要小心!一個觸發器不是一個約束 - 想想如果兩個用戶更新表,等等會發生什麼......

+1

觸發器不起作用,因爲OP想跨越記錄強制執行一個約束,這會導致表異常變異。 – APC

+1

感謝@APC的評論,我不知道什麼OP想要的......我明白它的方式是,你不應該允許插入一個值在'tvp_regione'中的記錄,除非有另一個在那領域。如果是這樣,然後觸發器可以工作(雖然不建議) –

+0

是的。我想扮演A.B.Cade的角色。有可能的?我如何制定觸發器? – Revious

3

我能想到的唯一方法是在刷新物化視圖上使用快速提交,使用查詢是這樣的:在MV表

select 
    tvp_codice_assoggetamen, 
    count(*)   rows_per_tca, 
    count(tvp_regione) tvp_regione_per_tca 
from 
    eni_trasc_voci_pwr_fatt 
group by 
    tvp_codice_assoggetamen 
/

將定期檢查約束,使得tvp_regione_per_tca = 1,如果rows_per_tca = 2(你的要求是不是很清楚,我)。

這通常是在Oracle中實現這種多行約束的唯一安全方式,在修改表和修改代碼以檢查之前,無法鎖定表。