Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / Oracle [игнор отключен] [закрыт для гостей] / История изменений в виде "поле, старое значение, новое значение" / 25 сообщений из 28, страница 1 из 2
21.09.2018, 12:00
    #39706047
rybingleb
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
История изменений в виде "поле, старое значение, новое значение"
Коллеги, прошу совета. Задача такая - показывать историю изменений заявок в виде:
название поля заявки

старое значение

новое значение.
И только те поля, которые изменились. То есть если из 10 полей поменялось значение в 3, то показывать только их.

Я сделал в таком виде:
Пишу старое и новое значение каждого поля в массив, дальше прохожусь по нему, если есть изменение значения, то пишу в таблицу с изменениями.

Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
...
elsif updating then
    add_rec('ID', 'ключевой идентификатор', to_str(:new.ID), to_str(:old.ID));
    add_rec('DOC_STATUS_ID', 'статус заявки', to_str(:new.DOC_STATUS_ID), to_str(:old.DOC_STATUS_ID));
    add_rec('REQUEST_TYPE_ID', 'тип заявки', to_str(:new.REQUEST_TYPE_ID), to_str(:old.REQUEST_TYPE_ID));
    add_rec('REQUEST_DATE', 'Дата заявки', to_str(:new.REQUEST_DATE), to_str(:old.REQUEST_DATE));
... еще куча полей  
   add_rec('ADVERTISING_SOURCES', 'источник рекламы', to_str(:new.ADVERTISING_SOURCES), to_str(:old.ADVERTISING_SOURCES));
    add_rec('PLACEORDER_ID', 'место принятия заявки', to_str(:new.PLACEORDER_ID), to_str(:old.PLACEORDER_ID));
    
    l_ind := l_rec.first;

    while l_ind is not null loop
      begin
        if (l_rec(l_ind).new_value <> l_rec(l_ind).old_value)
          or (l_rec(l_ind).new_value is not null and l_rec(l_ind).old_value is null)
          or (l_rec(l_ind).new_value is null and l_rec(l_ind).old_value is not null)
        then
          insert into tele2_request_history(
            id,
            changetype,
            changecolumn,
            newvalue,
            oldvalue,
            changeuser,
            changedate
          )
          values(
            :new.id,
            'UPD',
            l_rec(l_ind).column_comment,
            l_rec(l_ind).new_value,
            l_rec(l_ind).old_value,
            l_user,
            l_sysdate
          );
        end if;
      exception
        when others then
          xxfnd_error.log_error('tele2_request_history', l_ind||': '||sqlerrm);
      end;
      
      l_ind := l_rec.next(l_ind);
    end loop;
  end if;
...




Приходится перечислять все поля, и менять триггер при добавлении полей. Если забыть добавить, то изменения поля не будет писаться в историю.
Есть ли решение получше?
...
Рейтинг: 0 / 0
21.09.2018, 12:42
    #39706064
ma1tus
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
История изменений в виде "поле, старое значение, новое значение"
...
Рейтинг: 0 / 0
21.09.2018, 12:42
    #39706065
Elic
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
История изменений в виде "поле, старое значение, новое значение"
rybinglebЕсть ли решение получше? Генерировать
...
Рейтинг: 0 / 0
21.09.2018, 12:50
    #39706073
mibin
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
История изменений в виде "поле, старое значение, новое значение"
rybingleb,

Напиши JOB или DDL триггер который будет автоматически создавать тригер по изменению структуры и всё.
...
Рейтинг: 0 / 0
21.09.2018, 13:14
    #39706083
Stax
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
История изменений в виде "поле, старое значение, новое значение"
rybingleb
Приходится перечислять все поля, и менять триггер при добавлении полей. Если забыть добавить, то изменения поля не будет писаться в историю.
Есть ли решение получше?
імхо, изменение структуры дело серьезное, забыть поменять триггер сложно

вспомнят, поменяете

зы
я б массив не запролнял, сразу в add_rec делал инсерт с учетом изменений

....
stax
...
Рейтинг: 0 / 0
21.09.2018, 14:36
    #39706138
andrey_anonymous
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
История изменений в виде "поле, старое значение, новое значение"
rybinglebЕсть ли решение получше?
Если бы оракель не решил прибить oracle streams, то оно было бы "самое то".
Если есть возможность - посмотрите на Golden Gate или его аналоги.
Кроме того, возможно что-то построить просто на базе logminer.
...
Рейтинг: 0 / 0
21.09.2018, 15:25
    #39706174
Elic
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
История изменений в виде "поле, старое значение, новое значение"
andrey_anonymousЕсли бы оракель не решил прибить oracle streams, то оно было бы "самое то".
Если есть возможность - посмотрите на Golden Gate или его аналоги.
Кроме того, возможно что-то построить просто на базе logminer.Из пушки - по амёбам.
...
Рейтинг: 0 / 0
21.09.2018, 15:40
    #39706184
Leonid Kudryavtsev
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
История изменений в виде "поле, старое значение, новое значение"
rybinglebПриходится перечислять все поля, и менять триггер при добавлении полей. Если забыть добавить, то изменения поля не будет писаться в историю.
Есть ли решение получше?
в системе с которой сейчас работаю, аналогичную задачу сделали на динамическом SQL

Использование динамического SQL в триггерах - вводит в шок, но как-то работает. Производительность ниже плинтуса, но сервер пока вытягивает.
...
Рейтинг: 0 / 0
21.09.2018, 15:54
    #39706196
Stax
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
История изменений в виде "поле, старое значение, новое значение"
Leonid Kudryavtsev,

:new/:old видны в execute immediate?

.....
stax
...
Рейтинг: 0 / 0
21.09.2018, 15:59
    #39706206
Leonid Kudryavtsev
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
История изменений в виде "поле, старое значение, новое значение"
Stax
Я в этот код еще даже и не заглядывал. Но на удивление работает )))
...
Рейтинг: 0 / 0
21.09.2018, 16:12
    #39706213
Elic
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
История изменений в виде "поле, старое значение, новое значение"
Leonid KudryavtsevЯ в этот код еще даже и не заглядывал. Но на удивление работает )))Скорее всего, ты чего-то напутал.
...
Рейтинг: 0 / 0
21.09.2018, 16:23
    #39706223
Leonid Kudryavtsev
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
История изменений в виде "поле, старое значение, новое значение"
ElicLeonid KudryavtsevЯ в этот код еще даже и не заглядывал. Но на удивление работает )))Скорее всего, ты чего-то напутал.
Переопределены триггеры:

BEFORE INSERT OR UPDATE OR DELETE --> Init_History()

INSERT OR DELETE OR UPDATE
REFERENCING OLD AS OLD NEW AS NEW
FOR EACH ROW --> Add_Key(v_Rec_ID, 'id', :NEW.ID); + Check_All_Keys() + куча другого кода

AFTER INSERT OR UPDATE OR DELETE ---> Close_Rec_In_History

В общем, IMHO допиленная классическая схема обхода table mutating. For each row - запоминаем ID, по окончанию statement'а, select'ом уже достаем данные из исходной таблицы и перекладываем в History

Подробно не смотрел. Не очень интересно. Я бы так не делал (полное убийство производительности).
...
Рейтинг: 0 / 0
21.09.2018, 16:53
    #39706233
Stax
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
История изменений в виде "поле, старое значение, новое значение"
Leonid Kudryavtsev,

'id' :NEW.ID вбито в код (как у rybingleb ), а надо формировать динамически, напр со словаря

....
stax
...
Рейтинг: 0 / 0
21.09.2018, 17:58
    #39706245
rybingleb
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
История изменений в виде "поле, старое значение, новое значение"
Всем спасибо.

Список полей я конечно не вручную набираю )
Код: plsql
1.
2.
3.
4.
5.
6.
select 'add_rec('''||c.COLUMN_NAME||''', '''||cm.COMMENTS||''', to_char(:new.'||c.COLUMN_NAME||'), to_char(:old.'||c.COLUMN_NAME||'));'
from all_tab_columns c, all_col_comments cm
where c.TABLE_NAME = 'TELE2_REQUESTS'
and cm.TABLE_NAME = c.TABLE_NAME
and cm.COLUMN_NAME = c.COLUMN_NAME
order by c.COLUMN_ID;



По поводу динамического SQL в первую очередь подумал, но там не видны :old и :new.

"Напиши JOB или DDL триггер который будет автоматически создавать тригер по изменению структуры и всё."
Ну это конечно для моей задачи слишком круто, не так уже часто будет определение таблицы меняться )
...
Рейтинг: 0 / 0
21.09.2018, 18:06
    #39706249
Leonid Kudryavtsev
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
История изменений в виде "поле, старое значение, новое значение"
На правах бреда (мозгового штурма)

а можно new и old в Java пропихнуть ?
...
Рейтинг: 0 / 0
21.09.2018, 18:26
    #39706255
Elic
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
История изменений в виде "поле, старое значение, новое значение"
Leonid Kudryavtsevа можно new и old в Java пропихнуть ?1) Накуя козе баян.
2) new - это ключевое слово, а не запись.
...
Рейтинг: 0 / 0
21.09.2018, 18:51
    #39706263
andrey_anonymous
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
История изменений в виде "поле, старое значение, новое значение"
Elicandrey_anonymousЕсли бы оракель не решил прибить oracle streams, то оно было бы "самое то".
Если есть возможность - посмотрите на Golden Gate или его аналоги.
Кроме того, возможно что-то построить просто на базе logminer.Из пушки - по амёбам.
Как сказать.
Если, скажем, в теле2 уже есть OGG - то все делается очень просто и без лишних плясок.

"По амёбам" - это так:
Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
create table dropme_l(id integer primary key, val varchar2(20), some_dt date default sysdate);
Table created
create materialized view log on dropme_l
tablespace users
cache noparallel
with primary key, sequence(val, some_dt)
including new values
;
Materialized view log created
insert into dropme_l(id, val) values (1, 'Initial');
1 row inserted
commit;
Commit complete
update dropme_l set val = 'changed' where id = 1;
1 row updated
commit;
Commit complete
delete dropme_l where id = 1;
1 row deleted
commit;
Commit complete
select sequence$$, dmltype$$, old_new$$, val, some_dt
  from mlog$_dropme_l
 order by sequence$$
;
SEQUENCE$$ DMLTYPE$$ OLD_NEW$$ VAL                  SOME_DT
---------- --------- --------- -------------------- -----------
         8 I         N         Initial              21.09.2018
         9 U         O         Initial              21.09.2018
        10 U         N         changed              21.09.2018
        11 D         O         changed              21.09.2018

SQL> 
...
Рейтинг: 0 / 0
21.09.2018, 19:15
    #39706272
SY
SY
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
История изменений в виде "поле, старое значение, новое значение"
Уточню - это если [C]LOBов нет.

SY.
...
Рейтинг: 0 / 0
21.09.2018, 20:00
    #39706277
andrey_anonymous
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
История изменений в виде "поле, старое значение, новое значение"
SYУточню - это если [C]LOBов нет.
...а про LONG RAW лучше вообще не вспоминать :)
...
Рейтинг: 0 / 0
22.09.2018, 20:51
    #39706457
rybingleb
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
История изменений в виде "поле, старое значение, новое значение"
andrey_anonymousElicпропущено...
Из пушки - по амёбам.
Как сказать.
Если, скажем, в теле2 уже есть OGG - то все делается очень просто и без лишних плясок.

Нету )

Elicselect sequence$$, dmltype$$, old_new$$, val, some_dt
from mlog$_dropme_l
order by sequence$$

Не очень с этим знаком. А эти логи не чистятся? Будет ли там история через год-два? Как со скоростью выборки из них, по дате например?
...
Рейтинг: 0 / 0
23.09.2018, 07:27
    #39706489
Elic
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
История изменений в виде "поле, старое значение, новое значение"
rybinglebElicselect sequence$$, dmltype$$, old_new$$, val, some_dt
from mlog$_dropme_l
order by sequence$$Цитировать научись.
...
Рейтинг: 0 / 0
23.09.2018, 12:27
    #39706522
SkilledJunior
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
История изменений в виде "поле, старое значение, новое значение"
rybinglebКоллеги, прошу совета. Задача такая - показывать историю изменений заявок в виде:
название поля заявки

старое значение

новое значение.
И только те поля, которые изменились. То есть если из 10 полей поменялось значение в 3, то показывать только их.

Я сделал в таком виде:
Пишу старое и новое значение каждого поля в массив, дальше прохожусь по нему, если есть изменение значения, то пишу в таблицу с изменениями.


Зачем мух и котлеты сваливать в одну кучу? Показывать пользователю некую формочку/отчет и обеспечить хранение информации это две разные задачи, сегодня требуется одна формочка, завтра еще две с другими требованиями по предоставлению данных.

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

И задача твоя не совсем понятна, если заявка меняется десять раз при этом все время меняются произвольные поля, одно поле может иметь несколько изменений, какое из старых значений ты должен при этом показывать?
...
Рейтинг: 0 / 0
23.09.2018, 20:11
    #39706652
Elic
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
История изменений в виде "поле, старое значение, новое значение"
SkilledJuniorРешение с транспонированием строк в столбцы имеет весьма серьезные недостатки, во первых ты потерял информацию о типах и выполняешь преобразование в строку без указания формата преобразованияТы хорошо подумал о том, кто на ком стоял?
...
Рейтинг: 0 / 0
24.09.2018, 00:43
    #39706718
SkilledJunior
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
История изменений в виде "поле, старое значение, новое значение"
ElicТы хорошо подумал о том, кто на ком стоял?
Когда записывал мысль уже не думал((, кончено же столбцы в строки, спасибо за поправку.
...
Рейтинг: 0 / 0
24.09.2018, 10:24
    #39706813
rybingleb
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
История изменений в виде "поле, старое значение, новое значение"
SkilledJuniorrybinglebКоллеги, прошу совета. Задача такая - показывать историю изменений заявок в виде:
название поля заявки

старое значение

новое значение.
И только те поля, которые изменились. То есть если из 10 полей поменялось значение в 3, то показывать только их.

Я сделал в таком виде:
Пишу старое и новое значение каждого поля в массив, дальше прохожусь по нему, если есть изменение значения, то пишу в таблицу с изменениями.


Зачем мух и котлеты сваливать в одну кучу? Показывать пользователю некую формочку/отчет и обеспечить хранение информации это две разные задачи, сегодня требуется одна формочка, завтра еще две с другими требованиями по предоставлению данных.

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

SkilledJuniorИ задача твоя не совсем понятна, если заявка меняется десять раз при этом все время меняются произвольные поля, одно поле может иметь несколько изменений, какое из старых значений ты должен при этом показывать?
Показывать надо все изменения
17.01.2018 в поле 1 значение 1 изменило на 2
17.01.2018 в поле 2 значение 1 изменило на 2
18.01.2018 в поле 1 значение 2 изменило на 3
ну и т.д.
...
Рейтинг: 0 / 0
Форумы / Oracle [игнор отключен] [закрыт для гостей] / История изменений в виде "поле, старое значение, новое значение" / 25 сообщений из 28, страница 1 из 2
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]