Триггер уровня на таблице A (т.е. library.borrows) не может запрашивать таблицу A. Если вы это сделаете, вы получите исключение для мутирующих таблиц (если вы не можете гарантировать, что вы будете onl y всегда делают однострочные вставки с предложением VALUES). Таким образом, это не будет считаться хорошей практикой развития в Oracle.
Самый логичный способ реализации такого рода требований - не через триггер. Вместо этого, если ваше приложение вызывает API хранимой процедуры, у вас будет хранимая процедура (например, CHECK_OUT), которая сначала запрашивает таблицу, чтобы определить, сколько книг, которые человек проверил, и вставляет строку в таблицу BORROWS только в том случае, если патрон ниже его лимит.
Второй подход заключается в том, чтобы сохранить количество элементов, извлеченных в отдельной таблице. Если у вас есть таблица Меценатов с колонкой NUM_CHECKED_OUT и ваш стол заимствует был PATRON_ID, чтобы указать, кто позаимствовал книгу, триггер может сделать что-то вроде
CREATE OR REPLACE TRIGGER CheckBorrowsTable
BEFORE INSERT ON library.borrows
FOR EACH ROW
BEGIN
UPDATE patrons p
SET p.num_checked_out = p.num_checked_out + 1
WHERE p.patron_id = :new.patron_id
END;
вместе с проверочным ограничением на столе Меценатов для того, чтобы NUM_CHECKED_OUT никогда не превышает 3.
Запрет на то, что это возможно, хотя и довольно громоздко, чтобы обойти ошибку мутирующего стола с помощью «трех триггерного решения».
- A Перед уровне оператора INSERT триггер очищает коллекцию, вы создали в пакете.
- ПЕРЕД НАЧАЛОМ ВСТАВКИ уровня строки записывает первичный ключ (или ROWID) , который изменяется в коллекции .
- после заявления INSERT триггер уровня считывает данные из коллекции, запрашивает таблицу, и определяет, будет ли какой-либо из вставок нарушили бизнес-правила. Если они сделали, выбросьте исключение.
Как вы можете себе представить, однако, три триггерных решения включают в себя множество движущихся частей, поэтому это не особенно целесообразно.
Вы также можете реализовать такие вещи с быстрым обновляемым материализованным представлением, но я не верю, что это вариант в экспресс-редакции базы данных (хотя я мог ошибаться в этом).
Следует отметить, что в многопользовательском сценарии это не сработает - два сеанса могут вставлять строки для одного и того же патрона, и оба будут обновлять таблицу патронов до того же значения, потому что они не будут видеть обновление другого сеанса , Вам потребуется сериализовать доступ к таблице патронов (например,'CHECK_OUT' сначала блокирует строку, обновляет ее, вставляет книгу, а затем фиксирует (которая освобождает блокировку)). –