Удаление без удаления

Запросы, планы, оптимизация запросов, ...

Модераторы: kdv, CyberMax

Ответить
Oleg Holod
Сообщения: 1
Зарегистрирован: 28 окт 2004, 18:27

Удаление без удаления

Сообщение Oleg Holod » 28 окт 2004, 18:44

Вопрос в том, как реализовать удаление без удаления? Т.е. так чтобы при удалении, например, срабатывал триггер который, вставляя новую и апдейтя старую запись ничего не удалял из таблицы?

Если интересно - предыстория:
Есть самоссылочные таблицы со след. структурой:
CREATE TABLE "TObject" (
"ObjectID" "TableID" NOT NULL, // Сериальник на генераторе
... информационные поля ....
"CreateTime" "DateTime" NOT NULL, // Дата создания информации
"ChangeTime" "DateTime", // Дата перехода инф-ции в действительное состояние
"CreatedByUserID" "GuideID" NOT NULL, // Пользователь создавший информацию
"ActualID" "NullableTableID"); // Ссылка на действительную информацию в этой же таблице

ALTER TABLE "TObject" ADD CONSTRAINT "PK_TObject" PRIMARY KEY ("ObjectID");

При появлении нового объекта добавляется новая запись, в которой автоматически заполняются поля: ObjectID, CreateTime, CreatedByUserID

При изменении информации об объекте добавляется новая запись (новый сериальник) в которую переносится вся старая информация об объекте + поля: CreateTime, CreatedByUserID; а также у нее (у новой записи) заполняются поля ChangeTime, ActualID. Где ActualID ссылка на старый сериальник. А старая запись заполняется новой информацией, в том числе меняются поля: CreateTime, CreatedByUserID (ChangeTime и ActualID остаются пустыми)

При удалении объекта добавляется новая запись (новый сериальник) в которую переносится вся информация об объекте + поля: CreateTime, CreatedByUserID; а также у нее (у новой записи) заполняются поля ChangeTime, ActualID. Где ActualID ссылка на старый сериальник. А в старой записи меняются поля: CreateTime, CreatedByUserID, ChangeTime и ActualID. Где ChangeTime = CreatedByUserID, а ActualID ссылается на саму себя. Такие сложности при удалении связаны с тем, что нам необходимо хранить, кто удалил объект. Если мы просто у старой записи бы поставили ActualID равен своему же сериальнику и проапдейтили CreatedByUserID и ChangeTime, то потеряли бы информацию о том пользователе, который делал последние перед удалением изменения.


Для чего это сделано:
1. Сохранять всю историю информации с сохранением кто и когда менял.
2. Не создаем дополнительной таблицы истории, что позволяет нам делать запросы по информации актуальной на произвольный момент времени.

kdv
Forum Admin
Сообщения: 6595
Зарегистрирован: 25 окт 2004, 18:07

Сообщение kdv » 28 окт 2004, 19:09

можно использовать механизм аля sap/r3 - ввести таблицу "команд".
когда в такую таблицу делается инсерт, то в зависимости от набора столбцов и столбца "действие" триггеры делают те или иные операции.
при успешной их обработке триггером запись удаляет сама себя.

Правда, тут вообще никаких удалений нет, всегда только инсерт :-)

p.s. и я не помню, работала такая схема или глючила - делал это еще на 5.x.

Гость

Сообщение Гость » 28 окт 2004, 19:30

Есть вариант, запретить все прямые операции над таблицами, все действия делать с помощью процедур с правами.

Есть еще один, но он попахивает маразмом и толком незнаю будет работать или нет. Делать вставку старых занчений на AfterDelete. Надо глянуть в триггере на AfterDelete есть информация об удаленной записи. Боюсь что нет.

dimitr
Разработчик Firebird
Сообщения: 888
Зарегистрирован: 26 окт 2004, 16:20

Сообщение dimitr » 28 окт 2004, 23:02

Такие проблемы изящно решаются с помощью обновляемых через триггеры вьюх.

Vemer
Сообщения: 8
Зарегистрирован: 09 ноя 2004, 15:01

Сообщение Vemer » 09 ноя 2004, 15:22

У меня это через поле статуса делаеться + контроль в ХП. и никаких трипперов, тьфу - триггеров )). Зачем городить лишние структуры?

eugeney
Сообщения: 79
Зарегистрирован: 29 окт 2004, 18:51

Re: Удаление без удаления

Сообщение eugeney » 03 дек 2004, 15:58

Oleg Holod писал(а):Вопрос в том, как реализовать удаление без удаления? Т.е. так чтобы при удалении, например, срабатывал триггер который, вставляя новую и апдейтя старую запись ничего не удалял из таблицы?

Для чего это сделано:
1. Сохранять всю историю информации с сохранением кто и когда менял.
2. Не создаем дополнительной таблицы истории, что позволяет нам делать запросы по информации актуальной на произвольный момент времени.
Есть два решения одно шибко красивое View+Trigger.
Второе немного попроще. Смотря какими компонентами доступа к БД пользуешся если FIB/IBX, то тогда
1. Пишеш хранимую процедуру которая выполняет нужные тебе действия.
2. В deleteSQL пишеш execute procedure ...
Остается проблемма в том как обновить запись.

Как итог тебе нужно завуалировать delete в восприятии БД. Или скрыть посредством View+Trigger или писать execute procedure ... вместо delete ...

Путилин Евгений.

Ответить