Гость
Форумы / Firebird, InterBase [игнор отключен] [закрыт для гостей] / Узнать имя таблицы из триггера / 25 сообщений из 90, страница 1 из 4
09.07.2008, 14:04
    #35420366
X11
X11
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Узнать имя таблицы из триггера
Прочёл эти две древние темы:

Получение имени "сработавшего" FK при INSERT'е в ХП
http://sql.ru/forum/actualthread.aspx?tid=409862&hl=%ee%ef%f0%e5%e4%e5%eb%e8%f2%fc+%e8%ec%ff+%f2%e0%e1%eb%e8%f6%fb#3928894


Может ли триггер узнать имя или номер таблицы для которой он вызывается?
http://sql.ru/forum/actualthread.aspx?tid=60592&hl=%ee%ef%f0%e5%e4%e5%eb%e8%f2%fc+%e8%ec%ff+%f2%e0%e1%eb%e8%f6%fb#430223

Вопрос в следующем. Может спустя столько лет появилась возможность узнать имя таблицы для которой срабатывает триггер? Может это будет в версии 2.х или 3.х?

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

Было бы вообще здорово, если бы была возможно создать один триггер для всех таблиц, в котором можно было бы определять значения контекстных переменных типа CURRENT_TABLE, CURRENT_TRIGGER, или что-то вроде этого.
...
Рейтинг: 0 / 0
09.07.2008, 14:15
    #35420416
arni
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Узнать имя таблицы из триггера
Разве бывают тригерры сразу на несколько таблиц?
По-любому триггер нацеливается лишь на одну.
Другое дело, что логику логирования можно не помещать в триггер,
а лишь вызывать из него например ХП, аргументом которой передавать имя таблицы.
В ХП по этому аргументу можно через обращение к системным таблицам узнать поля,
составить текст select'а, исполнять его через execute statement и далее уже логировать как душе удобно.

При такой схеме, триггеров будет много, но они будут состоять лишь из вызыва хранимки.
...
Рейтинг: 0 / 0
09.07.2008, 14:24
    #35420454
X11
X11
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Узнать имя таблицы из триггера
arniРазве бывают тригерры сразу на несколько таблиц?


вот я и про тоже, я имел ввиду, что хорошо бы, если бы они были
...
Рейтинг: 0 / 0
09.07.2008, 14:25
    #35420461
X11
X11
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Узнать имя таблицы из триггера
arni
Другое дело, что логику логирования можно не помещать в триггер,
а лишь вызывать из него например ХП, аргументом которой передавать имя таблицы.


Ну да, сейчас так и делаю. Просто таблиц многовато.
...
Рейтинг: 0 / 0
09.07.2008, 14:28
    #35420475
Мимопроходящий
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Узнать имя таблицы из триггера
X11 arniРазве бывают тригерры сразу на несколько таблиц?
X> вот я и про тоже, я имел ввиду, что хорошо бы, если бы они былиочередной всплеск гиперактивности мутантов...

--
With best regards, Мимопроходящий.

Posted via ActualForum NNTP Server 1.4
...
Рейтинг: 0 / 0
09.07.2008, 14:30
    #35420486
X11
X11
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Узнать имя таблицы из триггера
arni
Другое дело, что логику логирования можно не помещать в триггер,
а лишь вызывать из него например ХП, аргументом которой передавать имя таблицы.
В ХП по этому аргументу можно через обращение к системным таблицам узнать поля,
составить текст select'а, исполнять его через execute statement и далее уже логировать как душе удобно.

При такой схеме, триггеров будет много, но они будут состоять лишь из вызыва хранимки.
да, но вызываю хранимку, ей нужно передать имя триггера или имя таблицы, что на данный момент прописывается ручками.
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
CREATE OR ALTER TRIGGER SPR_COMMUNICATIONS_BIUD1 FOR SPR_COMMUNICATIONS
ACTIVE BEFORE INSERT OR UPDATE OR DELETE POSITION  1 
AS
declare variable table_name varchar( 100 );
begin
  if (coalesce(rdb$get_context('USER_SESSION','can_exp_change'),'1')='1' )
  then begin
      table_name = 'КОММУНИКАЦИИ';
-- хорошо бы так:       table_name = CURRENT_TABLE;

-- -------логирование
      if (inserting) then execute procedure sp_journaling(table_name,'ДОБАВЛЕНИЕ', new.id, null, null);
      if (updating) then execute procedure sp_journaling(table_name,'ИЗМЕНЕНИЕ', old.id, null, null);
      if (deleting) then begin
        execute procedure sp_journaling(table_name,'УДАЛЕНИЕ', old.id, null, null);
-- -------логирование

        execute procedure sp_send_to_deleted(old.id, 'SPR_COMMUNICATIONS_');
      end
  end
end
...
Рейтинг: 0 / 0
09.07.2008, 14:33
    #35420498
X11
X11
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Узнать имя таблицы из триггера
Мимопроходящий
X11 arniРазве бывают тригерры сразу на несколько таблиц?
X> вот я и про тоже, я имел ввиду, что хорошо бы, если бы они былиочередной всплеск гиперактивности мутантов...

--
With best regards, Мимопроходящий.

Posted via ActualForum NNTP Server 1.4

мерси за комплимент ))))))))
...
Рейтинг: 0 / 0
09.07.2008, 14:38
    #35420517
Лентяй
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Узнать имя таблицы из триггера
Напиши программу, которая будет вытаскивать список таблиц и для выбранных из списка по шаблону генерировать нужный текст триггера.
...
Рейтинг: 0 / 0
09.07.2008, 14:47
    #35420549
arni
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Узнать имя таблицы из триггера
X11
по-моему всякие "КОММУНИКАЦИИ", "ДОБАВЛЕНИЕ", "ИЗМЕНЕНИЕ" и "УДАЛЕНИЕ" - слишком жирно для и без того сумашедшим образом распухающих таблиц логгов. Все эти рюшки можно и при просмотре добавить.

Приведу кусок из своих закромов:

Код: plaintext
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.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
CREATE OR ALTER trigger SP_COLOR_LOG_I for SP_COLOR
active after insert position  1 
AS
begin
  --логгируем вставку строки
  execute procedure SYS_LOG_METADATA('SP_COLOR', new.ID, '+');
end

CREATE OR ALTER trigger SP_COLOR_LOG_U0 for SP_COLOR
active before update position  1 
AS
begin
  --логгируем изменение строки (фиксация старого состояния)
  execute procedure SYS_LOG_METADATA('SP_COLOR', old.ID, '<');
end

CREATE OR ALTER trigger SP_COLOR_LOG_U1 for SP_COLOR
active after update position  1 
AS
begin
  --логгируем изменение строки (фиксация нового состояния)
  execute procedure SYS_LOG_METADATA('SP_COLOR', new.ID, '>');
end

CREATE OR ALTER trigger SP_COLOR_LOG_D for SP_COLOR
active before delete position  1 
AS
begin
  --логгируем удаление строки
  execute procedure SYS_LOG_METADATA('SP_COLOR', old.ID, '-');
end

CREATE OR ALTER PROCEDURE SYS_LOG_METADATA(
    TBL_NAME VARCHAR( 32 ),
    TBL_ID INTEGER,
    TBL_OPER CHAR( 1 ))
AS
declare variable TEXT       varchar( 9999 ) default '';
declare variable SEPARATOR  varchar( 78 ) default '';
declare variable FLD        varchar( 32 );
declare variable STATM      varchar( 9999 ) default '';
begin
  --находим поля таблицы и формируем список выбора
  for
    select RDB$FIELD_NAME
      from RDB$RELATION_FIELDS
     where RDB$RELATION_NAME=:TBL_NAME
       and RDB$FIELD_NAME<>'ID'
     order by RDB$FIELD_POSITION
      into :FLD
  do begin
    FLD = trim(FLD);
    STATM = STATM || SEPARATOR || '''' || FLD || ' = ''' ||
      '||cast(coalesce(' || FLD || ','''') as varchar(200))';
    if (SEPARATOR='') then
      SEPARATOR = '||ascii_char(13)||ascii_char(10)||';
  end

  --формируем запрос
  STATM = 'select ' || STATM || ' from ' || TBL_NAME ||
    ' where ID=' || cast(TBL_ID as varchar( 9 ));

  --исполняем его
  execute statement STATM into :TEXT;

  --вставляем снимок строки в лог
  insert into SYS_LOG
    (MODULE, TBL_NAME, TBL_ID, TBL_OPER, TEXT)
  values
    ('(auto)', :TBL_NAME, :TBL_ID, :TBL_OPER, :TEXT);
end
...
Рейтинг: 0 / 0
09.07.2008, 14:52
    #35420567
Attid
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Узнать имя таблицы из триггера
ЛентяйНапиши программу, которая будет вытаскивать список таблиц и для выбранных из списка по шаблону генерировать нужный текст триггера.
можно даже SP =)
...
Рейтинг: 0 / 0
09.07.2008, 15:11
    #35420643
X11
X11
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Узнать имя таблицы из триггера
arni, спасибо. Переделаю, как у тебя. А то у меня немного не так.
...
Рейтинг: 0 / 0
09.07.2008, 15:32
    #35420731
X11
X11
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Узнать имя таблицы из триггера
arni, я смотрю, что ты не хранишь в логах имя пользователя, какой смысл логов?
...
Рейтинг: 0 / 0
09.07.2008, 15:35
    #35420741
WildSery
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Узнать имя таблицы из триггера
arni
Код: plaintext
SEPARATOR = '||ascii_char(13)||ascii_char(10)||';

Вот это вот - зачем? Не понял.
...
Рейтинг: 0 / 0
09.07.2008, 15:44
    #35420784
arni
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Узнать имя таблицы из триггера
X11arni, я смотрю, что ты не хранишь в логах имя пользователя, какой смысл логов?
есть такое поле с default user или в тригере через current_user цепляется - сейчас не помню, но вобщем автоматом садится
...
Рейтинг: 0 / 0
09.07.2008, 15:50
    #35420817
arni
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Узнать имя таблицы из триггера
WildSery arni
Код: plaintext
SEPARATOR = '||ascii_char(13)||ascii_char(10)||';

Вот это вот - зачем? Не понял.
Лог - это одно поле, куда в текстовом виде складываются все поля. Перевод строки нужен, чтобы при просмотре было удобочитабеельнее. Например:
Код: plaintext
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.
IZD_VID_ID = 3952
NUM = 3
ITEM_CAPTION = Крыша
EXACT_MAT_ID = 
EXACT_MAT_WIDTH = 
EXACT_COLOR_ID = 
F_MAT_BY_REF = =[МАТк]
F_MAT_WIDTH_BY_REF = =[ТЛЩк]
F_COLOR_BY_REF = =[ЦВЕТк]
SIZE1_KOD = 
SIZE1_CAPTION = 
F_SIZE1 = =[ШКш] + 4
SIZE2_KOD = 
SIZE2_CAPTION = 
F_SIZE2 = =[ШКг] + 100
KOL_KOD = 
F_KOL = [КОЛ]
F_PROF_BY_REF = 
F_TEMP_BEFORE = [Элит?]
F_PRIM = 
F_SIZE1_CUT = 
F_SIZE2_CUT = 
F_KOL_CUT = 
EXACT_DRAFT = 222000000001010
F_PRIM_CUT = 
ITEM_KIND_ID = 0
CAPTION_FACTOR_ID = 2
IF_SKIP_IN_CHILD = 0
...
Рейтинг: 0 / 0
09.07.2008, 15:58
    #35420848
WildSery
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Узнать имя таблицы из триггера
Лог глазами прямо из таблицы читаешь?
Я вот для этого отдельные процедуры/формы сделал. Зря старался?
...
Рейтинг: 0 / 0
09.07.2008, 16:13
    #35420909
X11
X11
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Узнать имя таблицы из триггера
arni по-моему всякие "КОММУНИКАЦИИ", "ДОБАВЛЕНИЕ", "ИЗМЕНЕНИЕ" и "УДАЛЕНИЕ" - слишком жирно для и без того сумашедшим образом распухающих таблиц логгов. Все эти рюшки можно и при просмотре добавить.
ага, особенно с полем, размер которого 10К.
...
Рейтинг: 0 / 0
09.07.2008, 16:22
    #35420960
X11
X11
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Узнать имя таблицы из триггера
arni
CREATE OR ALTER trigger SP_COLOR_LOG_U0 for SP_COLOR
active before update position 1
AS
begin
--логгируем изменение строки (фиксация старого состояния)
execute procedure SYS_LOG_METADATA('SP_COLOR', old.ID, '<');
end

CREATE OR ALTER trigger SP_COLOR_LOG_U1 for SP_COLOR
active after update position 1
AS
begin
--логгируем изменение строки (фиксация нового состояния)
execute procedure SYS_LOG_METADATA('SP_COLOR', new.ID, '>');


Не понятно, что даёт фиксация старого и нового состояния, тем более что значение ID, как правило не меняется.
т.е. в таблице будет две записи:
> ID = 12
< ID = 12
что из этого можно понять?

или в лог записываются старые и новые значения, так ля понял?
...
Рейтинг: 0 / 0
09.07.2008, 16:42
    #35421052
Гаджимурадов Рустам
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Узнать имя таблицы из триггера
X11Не понятно, что даёт фиксация старого и нового состояния, тем более
что значение ID, как правило не меняется.
т.е. в таблице будет две записи:
> ID = 12
< ID = 12
что из этого можно понять?
или в лог записываются старые и новые значения, так ля понял?
Нет. Там у него идет вызов ХР, которая в свою очередь селектит нужные поля
по указанному ID и записывает их в таблицу-лог (ну и таймштамп, думаю, добавляет).

"Ошибка" у arni в другом - нет смысла использовать два триггера, когда можно
обойтись одним (и фактически даже одним вызовом ХР). Единственное "но" -
это если у него сложная логика и цепочка триггеров - тогда ставить before-триггер
первым в цепочке, after-триггер - последним в цепочке.


Posted via ActualForum NNTP Server 1.4
...
Рейтинг: 0 / 0
09.07.2008, 16:48
    #35421081
arni
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Узнать имя таблицы из триггера
X11Не понятно, что даёт фиксация старого и нового состояния, тем более что значение ID, как правило не меняется.
т.е. в таблице будет две записи:
> ID = 12
< ID = 12
что из этого можно понять?

или в лог записываются старые и новые значения, так ля понял?
Разве плохо наблюдать в двух соседних строках состояние строки ДО и ПОСЛЕ правки?
...
Рейтинг: 0 / 0
09.07.2008, 16:52
    #35421095
arni
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Узнать имя таблицы из триггера
Гаджимурадов Рустам
"Ошибка" у arni в другом - нет смысла использовать два триггера, когда можно
обойтись одним (и фактически даже одним вызовом ХР). Единственное "но" -
это если у него сложная логика и цепочка триггеров - тогда ставить before-триггер
первым в цепочке, after-триггер - последним в цепочке.
Если бы логирование происходило в триггере, то действительно подтавляя сначала old.* значения, а потом new.* значения можно сохранить состояние и до и после. Перенося же логику в XП мы теряем все зацепки new.* и old.*. Остается только сканировать текущее значение. Поэтому вызов идет из двух триггеров.
...
Рейтинг: 0 / 0
09.07.2008, 16:56
    #35421109
Гаджимурадов Рустам
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Узнать имя таблицы из триггера
arniЕсли бы логирование происходило в триггере, то действительно подтавляя сначала old.* значения, а потом new.* значения
можно сохранить состояние и до и после. Перенося же логику в XП мы теряем все зацепки new.* и old.*. Остается только сканировать
текущее значение. Поэтому вызов идет из двух триггеров.
Отмазка не принята. Ничто (ну, кроме вышеназванных проблем с цепочками триггеров) не
мешает в одном триггере вызывать ХР два раза (один раз с OLD, другой раз с New).

В принципе, можно даже в ХР добавить еще один параметр, чтобы передавать old и new
одновременно, но это уже спорно - лучше / хуже.


Posted via ActualForum NNTP Server 1.4
...
Рейтинг: 0 / 0
09.07.2008, 17:04
    #35421139
arni
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Узнать имя таблицы из триггера
Гаджимурадов РустамОтмазка не принята. Ничто (ну, кроме вышеназванных проблем с цепочками триггеров) не
мешает в одном триггере вызывать ХР два раза (один раз с OLD, другой раз с New).

В принципе, можно даже в ХР добавить еще один параметр, чтобы передавать old и new
одновременно, но это уже спорно - лучше / хуже
Рустам, подумай: в хранимку я не передаю никаких реальных данных, только ID изменяемой строки.
Сама хранимка уже выбирает данные из рабочих таблиц по этому ID. Она ничего не знает про new.* и old.*. Она может только прочитать ТЕКУЩЕЕ значение. Текущим значением в фазе BEFORE за пределами самого триггера будет еще не измененная строка. Текущим значением в фазе AFTER за пределами самого триггера будет уже измененная строка. Т.о. перенося логиrу логирования за пределы триггера (в ХП) мы вынуждены дергать её дважды в двух тригерах на два состояния.
...
Рейтинг: 0 / 0
09.07.2008, 17:05
    #35421144
X11
X11
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Узнать имя таблицы из триггера
Странно

на строку
Код: plaintext
execute statement STATM into :TEXT;
can't format message 13:96 -- message system code -4.
Invalid argument in EXECUTE STATEMENT - cannot convert to string.
At procedure 'SP_SYS_LOG' line: 34, col: 3.


влияет ли то, что база в кодировке UTF8?
...
Рейтинг: 0 / 0
09.07.2008, 17:10
    #35421163
arni
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Узнать имя таблицы из триггера
X11Странно

на строку
Код: plaintext
execute statement STATM into :TEXT;
can't format message 13:96 -- message system code -4.
Invalid argument in EXECUTE STATEMENT - cannot convert to string.
At procedure 'SP_SYS_LOG' line: 34, col: 3.

глянь, что осаждается в переменной STATM.
Может там переполнение, либо с парностью кавычек напутал или еще чего...
...
Рейтинг: 0 / 0
Форумы / Firebird, InterBase [игнор отключен] [закрыт для гостей] / Узнать имя таблицы из триггера / 25 сообщений из 90, страница 1 из 4
Целевая тема:
Создать новую тему:
Автор:
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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