Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

Аудит триггером составной транзакции


Страницы:   1 2 3 4

Гость ©   (2010-02-03 10:40:00) 

Доброго дня!
Есть программа, которая выполняет в одной транзакции delete, insert, update. Есть триггер:

create or replace trigger SAMPLE_AUD
 before insert or delete or update on SAMPLE_TABLE
 for each row


, задача которого отловить все изменения и записать в таблицу аудита. Проблема в том, что отлавливается только insert. Можно ли сделать так, чтобы триггер отрабатывал на каждую команду в транзакции?


Sergey13   (2010-02-05 10:30:00) [41]

> [23] ANB   (05.02.10 10:05)

Он просто тупо большой и достаточно сложный если в него смотреть.
Дистрибутив ФБ весит 2.5 метра и сервер и клиент. Сколько весит Оракл?


ANB   (2010-02-05 10:05:00) [42]


> Для "некритичной базки" ни к чему юзать Оракл

А что юзать то ?
Оракл :
1) халявый
2) ставится за 5 минут задавая 3 вопроса
3) удобный


Sergey13   (2010-02-05 09:51:00) [43]

> [18] Кщд   (04.02.10 17:29)
> некритичной базке с 3-5 таблиц никто не будет поднимать
> архивлоги - это просто ни к чему

Для "некритичной базки" ни к чему юзать Оракл (хотя конечно не возбраняется 8-), и уж тем более прикручивать аудит. ИМХО.


Кщд   (2010-02-05 05:55:00) [44]

>Игорь Шевченко ©   (05.02.10 00:55) [20]
особенно хорош и гибок -  FGA
никто не спорит, да и пользовать его в той же 10-ке - очень удобно
вот только в обычной такой системе, где авторизация/аутентификация самописные(т.е. коннект происходит под одним пользователем Oracle), система разграничение прав своя и все изменения(DML) должны быть увязаны с OPERATION_LOG.ID(т.е. выполненной пользователем операции (или, например, идентификатором web-сессии), - все эти внутренние и, безусловно, эффективные инструменты несколько не к месту
другими словами, это, скорее, инструментарий dba, а не разработчика


Игорь Шевченко   (2010-02-05 00:55:00) [45]

RTFM Кулибиным:
http://download.oracle.com/docs/cd/B10500_01/server.920/a96521/audit.htm
http://www.oracle-base.com/articles/8i/Auditing.php
http://www.citforum.ru/database/oracle/audit/


Кщд   (2010-02-04 20:49:00) [46]

>Sergey13 ©   (04.02.10 13:14) [15]
перечитал Ваш пост внимательно)

>Разумеется в некоторых системах аудит необходим даже по закону, но >обычно люди пишущие его не задают вопросов на форумах.
ещё как задают))
здесь ещё немного кода и специфичных названий полей/таблиц - есть примеры, когда выкладывают код в несколько десятков килобайт...
только когда(и если) работодатель видит потроха базы и кода в форуме - ни к чему хорошему для вопрошавшего это не приводит


Кщд   (2010-02-04 17:29:00) [47]

>Sergey13 ©   (04.02.10 13:20) [16]
logminer пишет IP пользователя?)

а если серьезно, то, например, на простенькой, некритичной базке с 3-5 таблиц никто не будет поднимать архивлоги - это просто ни к чему

да и с помощью sql работать куда как приятнее - опять же можно в софтину клиентскую привязать показ изменений


Кщд   (2010-02-04 17:25:00) [48]

>ANB   (04.02.10 12:30) [14]
>Да ничего страшного вообще то
0!=null - логическая ошибка
т.о. при изменении 0 на null и обратно, изменение не будет учтено

>Вполне нормально. Старое и новое значение.
вопрос был "зачем"
если бездумно плодить данные - нормально, то остается только умыть руки

>SELECT SEQ_INASTRBUD_AUD.NEXTVAL INTO New_Idaud FROM Dual;
т.е. если ID2 > ID1, то изменения в ID2 - более поздние, так?

>Короче, вполне себе так нормальный триггер. Я бы еще поле для sysdate добавил - не помешает.
timestamp
и, желательно, с local time zone
впрочем, это уже излишество, но весьма полезное время от времени


Sergey13   (2010-02-04 13:20:00) [49]

Плюсом про аудит.
В Оракле (насколько я понял это он) вроде как есть штатное средство по работе со штатными логами. Log Miner вроде называется. Я с ним не разбирался, но вроде как по отзывам вполне работоспособен. А логах оракла есть все.


Sergey13   (2010-02-04 13:14:00) [50]

Насчет аудита я скажу так. Я бы трижды подумал на тему - а нужен ли он такой. Пробовал несколько раз делать такое - очень скоро аудитные таблицы начинают превосходить исходные по объему на порядки. При этом используется он ОЧЕНЬ (обычно) редко и не дает особо ничего. Ну нашли виновника, и что? "Ну ошибся я, с кем не бывает". И ВСЕ. Я бы просто добавил логин юзера и дату последней модификации записи в основную таблицу. В 99% случаев этогшо достаточно.

Разумеется в некоторых системах аудит необходим даже по закону, но обычно люди пишущие его не задают вопросов на форумах.

ИМХО

ЗЫ: Я так и не понял как влияло некорректное сравнение с нулом на секцию тригера про удаление.


ANB   (2010-02-04 12:30:00) [51]


> null = 0
> с такой логикой далеко не уедешь

Да ничего страшного вообще то


> также, не ясно, зачем при update плодить две записи

Вполне нормально. Старое и новое значение.

> но как Вы собираетесь определять очередность изменений при
> таком подходе

SELECT SEQ_INASTRBUD_AUD.NEXTVAL INTO New_Idaud FROM Dual;

Короче, вполне себе так нормальный триггер. Я бы еще поле для sysdate добавил - не помешает.

И стандартная ошибка при сравнении (забыли про null). Я так тоже люблю косячить. Правда, в последнее время уже очень редко.


Кщд   (2010-02-03 18:33:00) [52]

Гость   (03.02.10 15:24) [9]
null = 0
с такой логикой далеко не уедешь
также, не ясно, зачем при update плодить две записи и почему в логе нет timestamp?
допустим, двойной вставкой при update страхуетесь от того, что два пользователя одновременно редактируют запись(а Вам, видимо, хочется видеть что менял пользователь и на что, на случай lost update), но как Вы собираетесь определять очередность изменений при таком подходе - совершенно непонятно
trim, опять же, где нужно и где не нужно

и принято сообщать, СУБД и версию
удачи)


Anatoly Podgoretsky   (2010-02-03 16:01:00) [53]

> Ega23  (03.02.2010 15:55:11)  [11]

Update по сути такой и есть, а внутреннея реализация не интересна.


Ega23   (2010-02-03 15:55:00) [54]

А как в Oracle Update работает?
У меня складывается глубокое убеждение, что в MSSQL он "в кишках" как delete-insert работает.


Sergey13   (2010-02-03 15:42:00) [55]

> [9] Гость   (03.02.10 15:24)

А как это влияло на НЕсрабатывании на удаление? Или ты не удалял?


Гость   (2010-02-03 15:24:00) [56]

Спасибо, все решилось!

Дело было в ошибке сравнения с NULL. Надо так:

 IF Updating THEN
   IF nvl(:old.IDNTYPBUDG, 0) <> nvl(:new.IDNTYPBUDG, 0) OR
      nvl(:old.IDNBACC, 0) <> nvl(:new.IDNBACC, 0) OR
      nvl(:old.IDNBUDGET, 0) <> nvl(:new.IDNBUDGET, 0) OR
      nvl(:old.IDINASTRBUD, 0) <> nvl(:new.IDINASTRBUD, 0) THEN


Кщд   (2010-02-03 13:33:00) [57]

триггеры аудита обычно вешают на after
а конкретно по теме: тест-кейс из sqlplus в студию, пожалуйста


Гость   (2010-02-03 11:12:00) [58]

пробовал, отрабатывает один, по последней команде


Sergey13   (2010-02-03 11:10:00) [59]

> [5] Гость   (03.02.10 10:56)
на первый взгляд вроде все логично.
А если сделать три отдельных тригера на каждое действие?


Гость   (2010-02-03 10:56:00) [60]

create or replace trigger INASTRBUD_AUD
 before insert or delete or update on INASTRBUD
 for each row
declare
 New_Idaud xx_audit.INASTRBUD_AUD.IDAUD%TYPE;
begin
 SELECT SEQ_INASTRBUD_AUD.NEXTVAL INTO New_Idaud FROM Dual;
 IF Updating THEN
   IF :old.IDNTYPBUDG <> :new.IDNTYPBUDG OR :old.IDNBACC <> :new.IDNBACC OR
      :old.IDNBUDGET <> :new.IDNBUDGET OR
      :old.IDINASTRBUD <> :new.IDINASTRBUD THEN
     INSERT INTO xx_audit.INASTRBUD_AUD
       (IDNTYPBUDG,
        IDNBACC,
        IDNBUDGET,
        IDINASTRBUD,
        IDAUD,
        DML_TYPE,
        DML_TYPEU,
        TERMINAL,
        OS_USER,
        IP_ADRES,
        SESSION_USER)
     VALUES
       (:old.IDNTYPBUDG,
        :old.IDNBACC,
        :old.IDNBUDGET,
        :old.IDINASTRBUD,
        New_Idaud,
        'U',
        '0',
        TRIM(Sys_Context('userenv', 'TERMINAL')),
        TRIM(Sys_Context('userenv', 'OS_USER')),
        TRIM(Sys_Context('userenv', 'IP_ADDRESS')),
        TRIM(Sys_Context('userenv', 'SESSION_USER')));
     INSERT INTO xx_audit.INASTRBUD_AUD
       (IDNTYPBUDG,
        IDNBACC,
        IDNBUDGET,
        IDINASTRBUD,
        IDAUD,
        DML_TYPE,
        DML_TYPEU,
        TERMINAL,
        OS_USER,
        IP_ADRES,
        SESSION_USER)
     VALUES
       (:new.IDNTYPBUDG,
        :new.IDNBACC,
        :new.IDNBUDGET,
        :new.IDINASTRBUD,
        New_Idaud,
        'U',
        '1',
        TRIM(Sys_Context('userenv', 'TERMINAL')),
        TRIM(Sys_Context('userenv', 'OS_USER')),
        TRIM(Sys_Context('userenv', 'IP_ADDRESS')),
        TRIM(Sys_Context('userenv', 'SESSION_USER')));
   END IF;
 ELSIF Inserting THEN
   INSERT INTO xx_audit.INASTRBUD_AUD
     (IDNTYPBUDG,
      IDNBACC,
      IDNBUDGET,
      IDINASTRBUD,
      IDAUD,
      DML_TYPE,
      DML_TYPEU,
      TERMINAL,
      OS_USER,
      IP_ADRES,
      SESSION_USER)
   VALUES
     (:new.IDNTYPBUDG,
      :new.IDNBACC,
      :new.IDNBUDGET,
      :new.IDINASTRBUD,
      New_Idaud,
      'I',
      '',
      TRIM(Sys_Context('userenv', 'TERMINAL')),
      TRIM(Sys_Context('userenv', 'OS_USER')),
      TRIM(Sys_Context('userenv', 'IP_ADDRESS')),
      TRIM(Sys_Context('userenv', 'SESSION_USER')));
 ELSE
   INSERT INTO xx_audit.INASTRBUD_AUD
     (IDNTYPBUDG,
      IDNBACC,
      IDNBUDGET,
      IDINASTRBUD,
      IDAUD,
      DML_TYPE,
      DML_TYPEU,
      TERMINAL,
      OS_USER,
      IP_ADRES,
      SESSION_USER)
   VALUES
     (:old.IDNTYPBUDG,
      :old.IDNBACC,
      :old.IDNBUDGET,
      :old.IDINASTRBUD,
      New_Idaud,
      'D',
      '',
      TRIM(Sys_Context('userenv', 'TERMINAL')),
      TRIM(Sys_Context('userenv', 'OS_USER')),
      TRIM(Sys_Context('userenv', 'IP_ADDRESS')),
      TRIM(Sys_Context('userenv', 'SESSION_USER')));
 END IF;
end INASTRBUD_AUD;


Страницы:   1 2 3 4

Наверх

Титульная страница Поиск, карта сайта Написать письмо