Отмена вставки в триггере MySQL

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

Проблема в том, что отменить запрос в триггере MySQL тривиальным образом нельзя. В той же MS SQL Server есть INSTEAD OF и достаточно просто прописать в триггере ROLLBACK, что бы отменить вставку, но в MySQL команды транзакций использовать в триггерах нельзя.

Можно ли триггером в MySQL корректно отменить запись строки в базу? Нужен триггер запрещающий вставку. Есть несколько способов решения этой проблемы.

Вызов ошибки в триггере

Вызвав ошибку в триггере можно отменить выполнение запроса вызвавшего триггер.
К сожалению, в триггерах MySQL сейчас нет возможности корректно откатить транзакцию.
Самое лучшее (несмотря на то, что оно ужасно) решение сейчас — сделать какую-то ошибку.

Например, так:

create trigger bi_a before insert on a for each row insert into you_cannot_insert_into_this_table_because_of_the_trigger_check values ();

Табличка с длинным названием, конечно, не должна существовать. Выглядит как костыль, костыль и есть.

Удаление текущего потока

Триггер: Before Insert, Before Update, Before Delete.

IF  THEN 
KILL QUERY CONNECTION_ID(); 
END IF;

Вызов процедуры из триггера

триггер before insert — OLD в нем нет. Если ничего не нужно делать — RETURN null;

begin;
drop table a, b cascade;
drop function if exists tgf_b_bi () cascade;

create table a (id serial primary key, v varchar);
create table b (id serial primary key, a_id integer, v varchar, constraint fk_b_a_id foreign key (a_id) references a(id));

create or replace function tgf_b_bi () returns trigger as $$
begin
  if not exists(select id from a where id = new.a_id) then
    return null;
  else
    return new;
  end if;
end
$$ language plpgsql;
create trigger tg_a_bi before insert on b for each row execute procedure tgf_b_bi();

insert into a values (default, '1') ;
insert into b values (default, 1, '1') ;
insert into b values (default, 2, '2') ;

rollback;

Такие дела в общем.

Поделиться!
Tags: , , , ,

49.72MB | MySQL:54 | 0,294sec