Оракул и мутирующий стол с простым упражнением - PullRequest
0 голосов
/ 01 февраля 2019

У меня проблемы с реализацией триггера.Предполагая, что у меня есть два типа:

CREATE TYPE customer_t AS OBJECT( 
code INTEGER,
name VARCHAR(20),
surname VARCHAR(20),
age INTEGER);

и тип

CREATE TYPE ticket_t AS OBJECT (
price INTEGER,
cust REF customer_t
)

И затем у меня есть связанные таблицы:

CREATE TABLE customers OF TYPE customer_t

CREATE TABLE tickets OF TYPE ticket_t

Я должен сделатьупражнение, поэтому мне нужно создать триггер, чтобы клиент не купил больше 10 билетов, но, если я использую команду типа «выбрать количество (*)», я получу ошибку, потому что не могу получить доступ к таблице мутаций.

Пожалуйста, кто-нибудь может мне помочь с этим триггером?

РЕДАКТИРОВАТЬ:

Я заполнил таблицы следующим образом:

INSERT INTO custs (code, name, surname, age) values (123, 'Paolo', 'Past', 32);

и повторяя следующую операцию десять раз:

INSERT INTO tickets (price, cust) values 
(4, (SELECT * FROM (SELECT REF(T) FROM custs T WHERE name = 'Paolo' AND surname = 'Past') WHERE rownum < 2))

Реализован триггер:

create or replace
trigger check_num_ticket after insert on tickets
for each row
declare 
   num_ticket number;
begin
SELECT count(*) INTO num_ticket FROM tickets WHERE :new.cust = cust;
if (num_ticket >= 10) then
  raise_application_error('-20099', 'no ticket available');
end if;
end;

И я получаю эту ошибку:

A trigger (or a user defined plsql function that is referenced in
this statement) attempted to look at (or modify) a table that was
in the middle of being modified by the statement which fired it.

1 Ответ

0 голосов
/ 01 февраля 2019

Вы получаете ошибку таблицы мутаций, потому что вы вставляете в ту же таблицу, в которую хотите получить количество строк.Представьте, что ваш оператор вставки вставляет две строки.Нет правила, какую строку вставлять первой, а какую - последней, но ваш триггер срабатывает на одной вставленной строке и хочет знать, сколько строк уже есть в таблице.СУБД сообщает, что это не определено, так как таблица в настоящее время мутирует.

Вам нужен триггер после оператора вместо триггера до строки.Поэтому, когда вставки оператора вставки сделаны, вы смотрите на таблицу, чтобы увидеть, есть ли внезапно клиенты с слишком большим количеством строк в ней.

(Отличная альтернатива - составной триггер. Он объединяет триггеры строк и операторов.Таким образом, в разделе после строки вы будете помнить клиентов в некотором массиве / коллекции, а в разделе после оператора вы будете искать таблицу только для запомненных клиентов.)

...