powered by simpleCommunicator - 2.0.51     © 2025 Programmizd 02
Форумы / Firebird, InterBase [игнор отключен] [закрыт для гостей] / Узнать имя таблицы из триггера
25 сообщений из 90, страница 1 из 4
Узнать имя таблицы из триггера
    #35420366
Фотография 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
Узнать имя таблицы из триггера
    #35420416
Фотография arni
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Разве бывают тригерры сразу на несколько таблиц?
По-любому триггер нацеливается лишь на одну.
Другое дело, что логику логирования можно не помещать в триггер,
а лишь вызывать из него например ХП, аргументом которой передавать имя таблицы.
В ХП по этому аргументу можно через обращение к системным таблицам узнать поля,
составить текст select'а, исполнять его через execute statement и далее уже логировать как душе удобно.

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


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


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

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

Posted via ActualForum NNTP Server 1.4
...
Рейтинг: 0 / 0
Узнать имя таблицы из триггера
    #35420486
Фотография 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
Узнать имя таблицы из триггера
    #35420498
Фотография X11
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Мимопроходящий
X11 arniРазве бывают тригерры сразу на несколько таблиц?
X> вот я и про тоже, я имел ввиду, что хорошо бы, если бы они былиочередной всплеск гиперактивности мутантов...

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

Posted via ActualForum NNTP Server 1.4

мерси за комплимент ))))))))
...
Рейтинг: 0 / 0
Узнать имя таблицы из триггера
    #35420517
Лентяй
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Напиши программу, которая будет вытаскивать список таблиц и для выбранных из списка по шаблону генерировать нужный текст триггера.
...
Рейтинг: 0 / 0
Узнать имя таблицы из триггера
    #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
Узнать имя таблицы из триггера
    #35420567
Фотография Attid
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ЛентяйНапиши программу, которая будет вытаскивать список таблиц и для выбранных из списка по шаблону генерировать нужный текст триггера.
можно даже SP =)
...
Рейтинг: 0 / 0
Узнать имя таблицы из триггера
    #35420643
Фотография X11
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
arni, спасибо. Переделаю, как у тебя. А то у меня немного не так.
...
Рейтинг: 0 / 0
Узнать имя таблицы из триггера
    #35420731
Фотография X11
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
arni, я смотрю, что ты не хранишь в логах имя пользователя, какой смысл логов?
...
Рейтинг: 0 / 0
Узнать имя таблицы из триггера
    #35420741
WildSery
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
arni
Код: plaintext
SEPARATOR = '||ascii_char(13)||ascii_char(10)||';

Вот это вот - зачем? Не понял.
...
Рейтинг: 0 / 0
Узнать имя таблицы из триггера
    #35420784
Фотография arni
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
X11arni, я смотрю, что ты не хранишь в логах имя пользователя, какой смысл логов?
есть такое поле с default user или в тригере через current_user цепляется - сейчас не помню, но вобщем автоматом садится
...
Рейтинг: 0 / 0
Узнать имя таблицы из триггера
    #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
Узнать имя таблицы из триггера
    #35420848
WildSery
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Лог глазами прямо из таблицы читаешь?
Я вот для этого отдельные процедуры/формы сделал. Зря старался?
...
Рейтинг: 0 / 0
Узнать имя таблицы из триггера
    #35420909
Фотография X11
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
arni по-моему всякие "КОММУНИКАЦИИ", "ДОБАВЛЕНИЕ", "ИЗМЕНЕНИЕ" и "УДАЛЕНИЕ" - слишком жирно для и без того сумашедшим образом распухающих таблиц логгов. Все эти рюшки можно и при просмотре добавить.
ага, особенно с полем, размер которого 10К.
...
Рейтинг: 0 / 0
Узнать имя таблицы из триггера
    #35420960
Фотография 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
Узнать имя таблицы из триггера
    #35421052
Гаджимурадов Рустам
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
X11Не понятно, что даёт фиксация старого и нового состояния, тем более
что значение ID, как правило не меняется.
т.е. в таблице будет две записи:
> ID = 12
< ID = 12
что из этого можно понять?
или в лог записываются старые и новые значения, так ля понял?
Нет. Там у него идет вызов ХР, которая в свою очередь селектит нужные поля
по указанному ID и записывает их в таблицу-лог (ну и таймштамп, думаю, добавляет).

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


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

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

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


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

В принципе, можно даже в ХР добавить еще один параметр, чтобы передавать old и new
одновременно, но это уже спорно - лучше / хуже
Рустам, подумай: в хранимку я не передаю никаких реальных данных, только ID изменяемой строки.
Сама хранимка уже выбирает данные из рабочих таблиц по этому ID. Она ничего не знает про new.* и old.*. Она может только прочитать ТЕКУЩЕЕ значение. Текущим значением в фазе BEFORE за пределами самого триггера будет еще не измененная строка. Текущим значением в фазе AFTER за пределами самого триггера будет уже измененная строка. Т.о. перенося логиrу логирования за пределы триггера (в ХП) мы вынуждены дергать её дважды в двух тригерах на два состояния.
...
Рейтинг: 0 / 0
Узнать имя таблицы из триггера
    #35421144
Фотография 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
Узнать имя таблицы из триггера
    #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
25 сообщений из 90, страница 1 из 4
Форумы / Firebird, InterBase [игнор отключен] [закрыт для гостей] / Узнать имя таблицы из триггера
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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