2014-11-10 6 views
0

Я пытаюсь создать функцию и триггер, которые проверяют, что количество столбцов wid и rdate внутри таблицы responsibility меньше или равно 10. Мне нужно создать исключение когда его больше 10.Проверка количества подзапросов не больше, чем x

Мой подсчет подсчета не работает. Когда COUNT() больше 10, исключение не выбрасывается.
Что я делаю неправильно?

CREATE FUNCTION check_10() RETURNS TRIGGER AS $$ 
BEGIN 
    IF (SELECT COUNT(CASE WHEN wid = NEW.wid AND rdate = NEW.rdate THEN 1 ELSE 0 END) AS total FROM resposibility) > 10 THEN 
     RAISE EXCEPTION 'MAXIMUM OF 10 CAGE RESPONSIBILITES FOR EACH WORKER PER DATE'; 
    END IF; 
    RETURN NEW; 
END; 
$$ LANGUAGE plpgsql; 

/* I've added update to make sure even when "updating" that row it will run the trigger check to verify */ 
CREATE TRIGGER insert_resp BEFORE INSERT OR UPDATE ON resposibility 
FOR EACH ROW EXECUTE PROCEDURE check_10(); 
+0

@ConsiderMe: Совершенно без цели. Функция триггера Postgres не работает. –

+0

Я предполагаю, что опечатка в вашем примере кода ('resposibility' without" n ") не имеет к этому никакого отношения? Триггер * будет казаться неэффективным, если вы действительно создали его за неправильную таблицу! –

ответ

1

Пока вы приподняв EXCEPTION (и не поймать его), что будет откат всей транзакции сразу в любом случае. В этом случае утверждение RETURN просто не имеет значения. Убери это.

Было бы альтернатива использовать RETURN NULLвместо за исключением, если вы хотите, чтобы спокойно пропустить операцию только на текущей строке и в противном случае проходят нормально.

Единственная очевидная ошибка в коде была > 10 вместо >= 10as pointed out by @a_horse. И опечатка в resposibility. Остальное - вопрос эффективности.

Кроме того, задания относительно дороги в plpgsql, здесь действительно не нужно. Упростить:

CREATE OR REPLACE FUNCTION check_10() 
    RETURNS TRIGGER AS 
$func$ 
BEGIN 
    IF (SELECT count(*) >= 10 
     FROM responsibility 
     WHERE wid = NEW.wid 
     AND rdate = NEW.rdate) THEN 

    RAISE EXCEPTION 'WORKER % ALREADY HAS MAX. OF 10 RESPONSIBILITES FOR DATE: %' 
     , NEW.wid, NEW.rdate; 
    -- no need for *any* RETURN statement here! 
    END IF; 

    RETURN NEW; 
END 
$func$ LANGUAGE plpgsql; 

Обязательно иметь индекс на wid и rdate или, в идеале, многоколоночной индекс по (wid, rdate).

+0

Когда я протестировал свой ответ, я ** ** включил 'return null' даже после' RAISE', чтобы выполнить эту работу. –

+1

@a_horse_with_no_name: Зачем вам это нужно? Не имеет значения, что происходит после исключения, оно никогда не выполняется (если вы не поймаете ошибку, что было бы необычным для триггерной функции). –

+0

Не знаю. По какой-то причине это не сработает. –

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