2016-01-14 3 views
0

я должен реализовать следующий триггер:Mutating стол - ошибка запуска

Общее количество голосов, за год выборов, выборов после 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

Я думаю, что проблема здесь не в «для каждой строки», а в выборе из себя. Просто удалите оператор select, я не думаю, что он вам действительно нужен: все, что вам нужно, это проверить: NEW.VOTES. – stee1rat

+0

'СОЗДАТЬ ИЛИ ЗАМЕНИТЬ ТРИГГЕР limit_election_votes до ВСТАВКИ ИЛИ ОБНОВЛЕНИЯ НА выборах объявить номер v_nbofvotes; начало выбрать сумму (голосов) в v_nbofvotes с выборов where election_year> 1960; if (v_nbofvotes> (538 * ((extract (year from sysdate)) - 1960))) THEN RAISE_APPLICATION_ERROR (-20500, 'Слишком много голосов'); 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

Хорошее решение, но не забывайте, что квалификатор «после 1960-х» – DanK

+0

Я лично не хочу использовать триггер, но это задача. – MonicaS

+0

на основе запроса в триггере кажется, что OP должен суммировать голоса от несколько строк, и в этом случае это не сработает, но не зная зерна данных, я не могу сказать точно. –

Смежные вопросы