Как обновить поле таблицы, после обновления другого поля
У меня есть две таблицы
CREATE TABLE account (
id SERIAL PRIMARY KEY,
username VARCHAR NOT NULL,
email VARCHAR NOT NULL UNIQUE,
phone VARCHAR NOT NULL UNIQUE
);
CREATE TABLE ticket (
id SERIAL PRIMARY KEY,
row INT NOT NULL,
col INT NOT NULL,
price INT NOT NULL CHECK (price > 0),
status VARCHAR NOT NULL,
account_id INT REFERENCES account(id)
);
Входные данные
insert into account(username, email, phone) values ('Kirill', '[email protected]', '+79653248496');
insert into account(username, email, phone) values ('Ivan', '[email protected]', '+79872753471');
insert into ticket(row, col, price, status, account_id) values (1, 1, 500, 'Free', null);
insert into ticket(row, col, price, status, account_id) values (1, 2, 550, 'Free', null);
insert into ticket(row, col, price, status, account_id) values (1, 3, 500, 'Free', null);
insert into ticket(row, col, price, status, account_id) values (2, 1, 600, 'Free', null);
insert into ticket(row, col, price, status, account_id) values (2, 2, 650, 'Free', null);
insert into ticket(row, col, price, status, account_id) values (2, 3, 600, 'Free', null);
insert into ticket(row, col, price, status, account_id) values (3, 1, 650, 'Free', null);
insert into ticket(row, col, price, status, account_id) values (3, 2, 700, 'Free', null);
insert into ticket(row, col, price, status, account_id) values (3, 3, 650, 'Free', null);
Как видно по умолчанию в таблице ticket поле status = Free, а account_id = null. Необходимо сделать так, чтобы после добавления account_id в какую-либо строку, например
update ticket set account_id = 1 where id = 5;
Поле status у данного элемента менялось на Taken. Я предположил, что необходимо создать функцию и триггер, написал такой код
CREATE FUNCTION update_status() RETURNS trigger AS $update_status$
BEGIN
IF new.account_id IS NOT NULL THEN
update ticket set status = 'Taken' where id = old.id;
END IF;
END;
$update_status$ LANGUAGE plpgsql;
CREATE TRIGGER update_status
AFTER INSERT OR UPDATE ON ticket
FOR EACH ROW EXECUTE PROCEDURE update_status();
У меня вылетает ошибка переполнения памяти, ошибка в строке
update ticket set status = 'Taken' where id = old.id;
Но как сделать правильно я не понимаю, с триггерами и функциями работал крайне редко, помогите пожалуйста
Ответы (1 шт):
Автор решения: Akina
→ Ссылка
Используйте generated column:
CREATE TABLE ticket (
id SERIAL PRIMARY KEY,
row INT NOT NULL,
col INT NOT NULL,
price INT NOT NULL CHECK (price > 0),
status VARCHAR NOT NULL GENERATED ALWAYS AS (CASE WHEN account_id IS NULL THEN 'Free' ELSE 'Taken' END) STORED,
account_id INT REFERENCES account(id)
);
https://dbfiddle.uk/?rdbms=postgres_12&fiddle=0295d811566fc6ca32161ee6377b19d7