К списку форумов К списку тем
Регистрация    Правила    Главная форума    Поиск   
Имя: Пароль:
Рекомендовать в новости

PostgreSql. Отменить удаление при удалении.

Гость
0 - 09.02.2012 - 11:51
Доброе утро.
Сижу, пытаюсь выстрелить себе в ногу )
Вобщем, есть таблица(ы), данные из которых удалять нельзя (как минимум 5 лет), но в тоже время необходимо всем показать, что кто-то их грохнул...
Для этого придумал завести дополнительное поле..(is_delete_row), куда хотелось бы при попытке удаления заносить дату и время... ну, штобы не плодить таблицы-клоны для хранения удаленных данных, ибо данные будут удаляться крайне редко.
Даже триггер написал на радостях. (оснорожно многа букав :) )

create or replace function trig_set_is_delete_row()
returns trigger as
$body$
begin
old.is_delete_row = localtimestamp;

/*и вот тут бы отменить удаление*/

return old;
end;
$body$
language plpgsql;

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

Камрады, есть еще способы? Гугл не в курсе...



Гость
1 - 09.02.2012 - 13:21
Вобщем делаю универсальную триггерную хранимку для всех таблиц с инсертом после делита... Пофиг на поле "дата создания записи" буду фиотровать оносительно даты удаления. :(

Хрень полная....
Гость
2 - 09.02.2012 - 13:41
Решение, что называется, в лоб:
вместо таблиц использовать вьюшки и понавешать триггеров "instead of".

P.S. Вьюшки нужны по той причине, что instead of не поддерживается на таблицах, а только на view.
Гость
3 - 09.02.2012 - 13:57
3-CPU > Ок, можно попробовать... Но почти законил хранимку, сейчас допишу - протестю. Если устроит оставлю ее, т.к. уже почти готовое решение. Иначе буду пробовать через "instead of"...
Гость
4 - 09.02.2012 - 15:01
Вот... получилось. Мож кому пригодиться...
Триггер после удаления возвращает запись обратно, запихивая при этом в поле is_delete_row текущую дату.

С каскадами (если дочерние таблицы не содержат указанного поля) пока не работает (удалит все). Времени мало. потом допилю.

create or replace function trig_set_is_delete_row_after_delete()
returns trigger as
$body$
declare
table_data_record record;
sql_select character varying;
sql_script character varying;
old_value character varying;
begin
sql_select:='';
sql_script:='';
for table_data_record in (select
col.column_name
from information_schema.columns col
where col.table_schema = quote_ident(TG_TABLE_SCHEMA) and
col.table_name = quote_ident(TG_TABLE_NAME)
order by col.ordinal_position)
loop
if length(sql_select) = 0 then
sql_select:=sql_select||'($1).'||table_data_record .column_name;
else
sql_select:=sql_select||','||'($1).'||table_data_r ecord.column_name;
end if;
end loop;
old.is_delete_row := localtimestamp;
sql_script:= 'insert into '||TG_TABLE_SCHEMA||'.'||TG_TABLE_NAME
||' select '||sql_select;

execute sql_script using old;
return old;
end;
$body$
language plpgsql;
Гость
5 - 09.02.2012 - 15:33
5-drmiller > А чего будет, если у тебя на такую таблицу будет еще триггер на insert?
Он будет срабатывать при каждом delete, что может привести к некорректному поведению.
Гость
6 - 09.02.2012 - 16:43
6-CPU >В таблицах, для которых предназначен этот триггер - обязательно есть поле "create_date", куда записывается время инсерта, т.е. фактически дата создания записи.
Данный триггер при инсерте после делита будет писать в это поле то значение которое там и было.
Сделовательно, для того чтобы небыло некорректного поведения + дата создания оставалась неизменной в триггере на инсерт нужно поставить маленькое условие:

if new.create_date is null then
new.create_date = localtimestamp;
/*+ любые необходимые действия*/
end if;
return new;

При исерте из моего триггера new.create_date всегда будет not null. А все остальные инсерты (внетриггерные) - пройдут как надо.

Да, согласен, код мягко говоря спецефичный... И требующий документации для тех кто будет это юзать. Но... в условиях бесконечной спешки и пинков для ускорения тщательно и хорошо делать не получаеца... :(( *пожаловался...типа*

п.с. хочу чтобы в сутрах было 60 часов :))
Гость
7 - 09.02.2012 - 16:45
Цитата:
Сообщение от drmiller Посмотреть сообщение
Данный триггер при инсерте после делита будет писать в это поле то значение которое там и было.
...писать в это поле (OLD-копию)....
Гость
8 - 09.02.2012 - 16:47
Поле create_date было заведено, естественно, не ради реализации этого механизма, а как информация для отлавливания глюков в перерасчетах, и других операциях бизнес логики по данным из БД :)
Гость
9 - 09.02.2012 - 21:29
от шо за люди? когда им без стеба советуют годное решение. они все равно пилят свое, кривоногий, храмое, сложное.

ты подумай о тех, кто будет сопровождать это все. подумай о себе, что ты можешь споткнуться об трудноуловимый косяк, стоит чуть более требований навешать.

вон cpu тебе ГОДНОЕ направление запилил. получишь простенькие, так сказать "линейные" инстед оф триггерки на вьюшках. просто, прозрачно, красиво, кашерно. нужное подчеркнуть.

нет же, ты создал кривожопое, неочевидное, наверняка с подводными корнями решение.

ну и зачем было вообще тему создавать?
Гость
10 - 10.02.2012 - 12:33
Цитата:
Сообщение от Продаются саженцы Посмотреть сообщение
вон cpu тебе ГОДНОЕ направление запилил. получишь простенькие, так сказать "линейные" инстед оф триггерки на вьюшках. просто, прозрачно, красиво, кашерно. нужное подчеркнуть.
Прочитал про "instead of". Чтобы им воспользоваться мне нужно вьюхи для каждой необходимой мне таблицы наплодить... Канечно это "просто, прозрачно, красиво, кашерно". Но "тех, кто будет сопровождать это все", при необходимости добавления этого функционала туда где его небыло, придется помимо добавления нужных полей и подключения уже имеющегося триггера - незабыть создать вьюху для того места где ее нет, и только к ней подцепить триггер.

Хотя если бы это необходимо было только для одной таблицы - это наилучший вариант.

Или я не прав? (что допустимо ибо о "instead of" впервые прочел только сегодня, и мож чего не уловил).

Ну и... "все равно пилят свое, кривоногий, храмое, сложное". Пока глюков незамечено, ну и сложность вроде как тоже терпимая (одна ветка if в триггре искривляет прямую логику) :) Вся сложность восприятия лечиться комментом в одно меленькое предложение (для потомков и сочувствующих).

м?


К списку вопросов






Copyright ©, Все права защищены