2016-01-14 54 views
0

我要實現以下觸發:變異表 - 觸發錯誤

票的總數,每個大選年,選舉的1960年後,不超過538

然而,我得到了突變表錯誤。我明白爲什麼我會得到這個錯誤,但我看不到另一個解決方案(帶觸發器)。我可以創建一個臨時表,但我只想要觸發器。 這裏是代碼:

CREATE OR REPLACE TRIGGER restrict_election_votes 
after INSERT OR UPDATE ON election 
for each row 
declare 
v_nbofvotes number; 
v_eleyr election.election_year%type :=:NEW.election_year; 
v_votes election.votes%type :=:NEW.VOTES; 

begin 
select sum(votes) 
into v_nbofvotes 
from election 
where election_year=v_eleyr; 

if(v_votes+v_nbofvotes >538) 
THEN 
    RAISE_APPLICATION_ERROR(-20500, 'Too many votes'); 
    END IF; 

END; 


update election 
set votes=175 
where candidate='MCCAIN J' 
and election_year=2008; 
+1

如果刪除了「每一行」,並使它成爲一個語句級觸發器(將不得不更改查詢,爲所有選舉檢查和規則(票)自1960年以來,你不知道是什麼行被插入/更新),那麼它應該工作。 –

+0

我認爲這裏的問題不是「爲每一行」而是從本身選擇。只要刪除選擇語句,我不認爲你真的需要在那裏:所有你需要的是檢查:NEW.VOTES。 – stee1rat

+0

'在INSERT或UPDATE ON選舉前創建或更換觸發器restrict_election_votes 聲明 v_nbofvotes數字; begin select sum(votes) into v_nbofvotes from election where election_year> 1960;如果(v_nbofvotes>(538 *((extract(from sysdate)) - 1960))) THEN RAISE_APPLICATION_ERROR(-20500,'Too many votes'); END IF; END;'仍然沒有工作 – MonicaS

回答

2

假設的問題是,你需要查詢選表,因爲計票總數是多行確定,然後如果你刪除了「每一行」並將其設置爲語句級別觸發器(必須將查詢更改爲檢查自1960年以來所有選舉的總和(投票)的規則,因爲您不知道插入/更新了哪行),那麼它將起作用。

create table mb_elct (year varchar2(4), cand varchar2(30), vt number) 

create or replace trigger mb_elct_trg 
after insert or update on mb_elct 
declare 
    v_nbofvotes number; 
begin 
select count(*) 
into v_nbofvotes 
from (
    select year, sum(vt) 
    from mb_elct 
    where year > '1960' 
    group by year 
    having sum(vt) >538 
); 

if(nvl(v_nbofvotes,0) != 0) 
THEN 
    RAISE_APPLICATION_ERROR(-20500, 'Too many votes'); 
    END IF; 

END; 
/

insert into mb_elct values ('2008', 'McCain', 500); 

1 row inserted 

update mb_elct set vt = vt + 200 where year = '2008' and cand = 'McCain'; 
ORA-20500: Too many votes 
ORA-06512: at "EDR_ADMIN.MB_ELCT_TRG", line 16 
ORA-04088: error during execution of trigger 'EDR_ADMIN.MB_ELCT_TRG' 
1

你確定你需要觸發嗎?你能解決這個問題,一個check constraint

alter table election add consntraint too_many_votes check (votes < 538 or year < 1960); 
+0

良好的解決方案,但一定要不要忘記「20世紀60年代後」限定符 – DanK

+0

我不親自想要使用觸發器,但這是任務.. – MonicaS

+0

基於觸發器中的查詢,似乎OP需要總結投票多行在這種情況下,這將無法正常工作,但不知道數據的穀物,我不能肯定地說.. –