Вы не можете сделать это с таблицами, но вы можете сделать это с представлениями.Представления могут иметь триггеры при вставке, обновлении и удалении, которые изменяют базовые таблицы.См. Также Обновляемые представления в справочнике по языку Firebird 2.5.
Короче говоря, создайте таблицу для данных, добавьте представление, добавьте триггеры, которые вставляют / обновляют / удаляют через представление вОсновная таблица.Пользователи могут затем использовать представление, как если бы оно было таблицей.
Пример
Я использую Firebird 3, но это будет работать с небольшими изменениями в Firebird 2.5 и более ранних версиях.
Таблица example_base
:
create table example_base (
id bigint generated by default as identity constraint pk_example_base primary key,
value1 varchar(100),
deleted boolean not null default false
)
Представление example
:
create view example (id, value1)
as
select id, value1
from example_base
where not deleted;
Не создавайте представление с with check option
, так как это запретит вставки какОтсутствие столбца deleted
в представлении не позволит Firebird проверить инвариант.
Затем добавьте триггер вставки:
create trigger tr_example_insert before insert on example
as
begin
if (new.id is not null) then
-- Don't use identity
insert into example_base(id, value1) values (new.id, new.value1);
else
-- Use identity
-- mapping generated id to new context
-- this way it is available for clients using insert .. returning
insert into example_base(value1) values (new.value1)
returning id into :new.id;
end
Приведенный выше триггер обеспечивает «по умолчанию как идентификатор»Первичный ключ базовой таблицы сохраняется и позволяет insert into example .. returning
сообщать о сгенерированном идентификаторе.
Триггер обновления
create trigger tr_example_update before update on example
as
begin
-- Consider ignoring modification of the id (or raise an exception)
update example_base
set id = new.id, value1 = new.value1
where id = old.id;
end
Приведенный выше триггер позволяет изменять первичный ключ;Вы можете захотеть просто игнорировать такую модификацию или даже вызвать исключение.
И, наконец, триггер удаления:
create trigger tr_example_delete before delete on example
as
begin
update example_base
set deleted = true
where id = old.id;
end
Этот триггер пометит запись в базовой таблице как удаленную.
Чтобы использовать это, просто предоставьте своим пользователям право выбирать, вставлять и обновлять права доступа к представлению (а не к таблице).
Единственное замечание, о котором я знаю, это то, что определение внешних ключей будетнужно указывать на example_base
, а не на example
, и поведение внешних ключей будет слегка отключено.Запись в базовой таблице будет продолжать существовать, поэтому внешний ключ не будет блокировать удаление.Если это то, что необходимо, вам нужно будет эмулировать поведение ограничения (что может быть сложно).