Модераторы: Akella
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> значение поля по имени поля в тригер, значение поля по имени поля в тригер 
:(
    Опции темы
Alam
Дата 15.3.2006, 15:38 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 2
Регистрация: 28.12.2005

Репутация: нет
Всего: нет



Имеются две таблицы:
I. Таблица с большим кол-вом полей (не важно сколько и какие).
II. Таблица из 4-х полей: 1 - UnKey (Уникальный ключ из первой таблицы), 2 - FieldName (Имя поля из первой таблицы) 3. OldVal (предыдущее значение поля) 4. NewVal (новое значение поля).
Задача следующая: При изменении записи первой таблицы во вторую должны внестись соответствующие записи об изменении того или иного поля.
В тригере BeforUpDate первой таблиы организован цикл перебора всех полей. Наименования полей получаем из системных таблиц.
Вопрос: Как получить значение New и Old наименованию поля, полученному из истемной таблицы?
PM MAIL   Вверх
TheCetus
Дата 15.3.2006, 17:23 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 134
Регистрация: 9.3.2006

Репутация: нет
Всего: 2



Используй контекстные переменные

Код

<TABLE FRAME="BOX" RULES="ALL" BORDER="1" CELLSPACING="0" CELLPADDING="0">
<TR ALIGN="LEFT" VALIGN="TOP">
<TD rowspan="3" ALIGN="LEFT" VALIGN="TOP">
<P class="text">
Тип триггера 
</P>
</TD>
<TD COLSPAN="4" ALIGN="LEFT" VALIGN="TOP">
<P class="text">
Контекстныепеременные 
</P>
</TD>
</TR>
<TR ALIGN="LEFT" VALIGN="TOP">
<TD COLSPAN="2" ALIGN="LEFT" VALIGN="TOP">
<P class="text">
NEW 
</P>
</TD>
<TD COLSPAN="2" ALIGN="LEFT" VALIGN="TOP">
<P class="text">
OLD 
</P>
</TD>
</TR>
<TR ALIGN="LEFT" VALIGN="TOP">
<TD COLSPAN="1" ROWSPAN="1" ALIGN="LEFT" VALIGN="TOP">
<P class="text">
Читать 
</P>
</TD>
<TD COLSPAN="1" ROWSPAN="1" ALIGN="LEFT" VALIGN="TOP">
<P class="text">
Изменять 
</P>
</TD>
<TD COLSPAN="1" ROWSPAN="1" ALIGN="LEFT" VALIGN="TOP">
<P class="text">
Читать 
</P>
</TD>
<TD COLSPAN="1" ROWSPAN="1" ALIGN="LEFT" VALIGN="TOP">
<P class="text">
Изменять 
</P>
</TD>
</TR>
<TR ALIGN="LEFT" VALIGN="TOP">
<TD COLSPAN="1" ROWSPAN="1" ALIGN="LEFT" VALIGN="TOP">
<P class="text">
BEFORE INSERT 
</P>
</TD>
<TD COLSPAN="1" ROWSPAN="1" ALIGN="LEFT" VALIGN="TOP">
<P class="text">

</P>
</TD>
<TD COLSPAN="1" ROWSPAN="1" ALIGN="LEFT" VALIGN="TOP">
<P class="text">

</P>
</TD>
<TD COLSPAN="1" ROWSPAN="1" ALIGN="LEFT" VALIGN="TOP">
<P class="text">
N/A 
</P>
</TD>
<TD COLSPAN="1" ROWSPAN="1" ALIGN="LEFT" VALIGN="TOP">
<P class="text">
N/A 
</P>
</TD>
</TR>
<TR ALIGN="LEFT" VALIGN="TOP">
<TD COLSPAN="1" ROWSPAN="1" ALIGN="LEFT" VALIGN="TOP">
<P class="text">
AFTER INSERT 
</P>
</TD>
<TD COLSPAN="1" ROWSPAN="1" ALIGN="LEFT" VALIGN="TOP">
<P class="text">

</P>
</TD>
<TD COLSPAN="1" ROWSPAN="1" ALIGN="LEFT" VALIGN="TOP">
<P class="text">
N/A 
</P>
</TD>
<TD COLSPAN="1" ROWSPAN="1" ALIGN="LEFT" VALIGN="TOP">
<P class="text">
N/A 
</P>
</TD>
<TD COLSPAN="1" ROWSPAN="1" ALIGN="LEFT" VALIGN="TOP">
<P class="text">
N/A 
</P>
</TD>
</TR>
<TR ALIGN="LEFT" VALIGN="TOP">
<TD COLSPAN="1" ROWSPAN="1" ALIGN="LEFT" VALIGN="TOP">
<P class="text">
BEFORE UPDATE 
</P>
</TD>
<TD COLSPAN="1" ROWSPAN="1" ALIGN="LEFT" VALIGN="TOP">
<P class="text">

</P>
</TD>
<TD COLSPAN="1" ROWSPAN="1" ALIGN="LEFT" VALIGN="TOP">
<P class="text">

</P>
</TD>
<TD COLSPAN="1" ROWSPAN="1" ALIGN="LEFT" VALIGN="TOP">
<P class="text">

</P>
</TD>
<TD COLSPAN="1" ROWSPAN="1" ALIGN="LEFT" VALIGN="TOP">
<P class="text">
N/A 
</P>
</TD>
</TR>
<TR ALIGN="LEFT" VALIGN="TOP">
<TD COLSPAN="1" ROWSPAN="1" ALIGN="LEFT" VALIGN="TOP">
<P class="text">
AFTER UPDATE 
</P>
</TD>
<TD COLSPAN="1" ROWSPAN="1" ALIGN="LEFT" VALIGN="TOP">
<P class="text">

</P>
</TD>
<TD COLSPAN="1" ROWSPAN="1" ALIGN="LEFT" VALIGN="TOP">
<P class="text">
N/A 
</P>
</TD>
<TD COLSPAN="1" ROWSPAN="1" ALIGN="LEFT" VALIGN="TOP">
<P class="text">

</P>
</TD>
<TD COLSPAN="1" ROWSPAN="1" ALIGN="LEFT" VALIGN="TOP">
<P class="text">
N/A 
</P>
</TD>
</TR>
<TR ALIGN="LEFT" VALIGN="TOP">
<TD COLSPAN="1" ROWSPAN="1" ALIGN="LEFT" VALIGN="TOP">
<P class="text">
BEFORE DELETE 
</P>
</TD>
<TD COLSPAN="1" ROWSPAN="1" ALIGN="LEFT" VALIGN="TOP">
<P class="text">
N/A 
</P>
</TD>
<TD COLSPAN="1" ROWSPAN="1" ALIGN="LEFT" VALIGN="TOP">
<P class="text">
N/A 
</P>
</TD>
<TD COLSPAN="1" ROWSPAN="1" ALIGN="LEFT" VALIGN="TOP">
<P class="text">

</P>
</TD>
<TD COLSPAN="1" ROWSPAN="1" ALIGN="LEFT" VALIGN="TOP">
<P class="text">
N/A 
</P>
</TD>
</TR>
<TR ALIGN="LEFT" VALIGN="TOP">
<TD COLSPAN="1" ROWSPAN="1" ALIGN="LEFT" VALIGN="TOP">
<P class="text">
AFTER DELETE 
</P>
</TD>
<TD COLSPAN="1" ROWSPAN="1" ALIGN="LEFT" VALIGN="TOP">
<P class="text">
N/A 
</P>
</TD>
<TD COLSPAN="1" ROWSPAN="1" ALIGN="LEFT" VALIGN="TOP">
<P class="text">
N/A 
</P>
</TD>
<TD COLSPAN="1" ROWSPAN="1" ALIGN="LEFT" VALIGN="TOP">
<P class="text">

</P>
</TD>
<TD COLSPAN="1" ROWSPAN="1" ALIGN="LEFT" VALIGN="TOP">
<P class="text">
N/A 
</P>
</TD>
</TR>
</TABLE>



пример использования

Код

trigger before insert
begin
  if (New.Id is null) then
    New.ID = Gen_Id(My_Gen,1);
end;

trigger before update
begin
  if ((New.ID is null) or (New.ID <> Old.ID)) then
    New.ID = Old.ID;
end;


Добавлено @ 17:28
упс ошибочка вышла с табличокй...
вставляю чистым текстом

Код

Тип триггера  Контекстныепеременные 
              NEW              OLD 
              Читать Изменять  Читать  Изменять 
BEFORE INSERT Y      Y         N/A     N/A 
AFTER INSERT  Y      N/A       N/A     N/A 
BEFORE UPDATE Y      Y         Y       N/A 
AFTER UPDATE  Y      N/A       Y       N/A 
BEFORE DELETE N/A    N/A       Y       N/A 
AFTER DELETE  N/A    N/A       Y       N/A


PM MAIL   Вверх
Alam
Дата 16.3.2006, 17:46 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 2
Регистрация: 28.12.2005

Репутация: нет
Всего: нет



Да мне так и приходиться выкручиваться. Но в таблице около ста полей (и таблица не одна) и тригер получается амбарный и если добавлять поля в таблицу приходиться добписывать и тригер под эти поля. Было бы идеально если перебратьв цикле все поля таблицы получая их наименования из ситемных полей и на каждом шаге сравнивать значения New и Old. Проблема в получении этих значений по наименованию полей. Хочу что то типа как в Delphi - Table.FieldByName('FieldName'). Если это не возможно скажите - не буду smile
PM MAIL   Вверх
Linco
Дата 23.3.2006, 16:16 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 8
Регистрация: 14.2.2006

Репутация: нет
Всего: нет



Невозможно, пока. Ибо по ресурсам нехорошо, и легче написать свой генератор триггеров либо воспользоваться интерфейсом от сторонних производителей (IBExpert)
PM MAIL   Вверх
Akella
Дата 4.5.2006, 08:33 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Творец
****


Профиль
Группа: Модератор
Сообщений: 18485
Регистрация: 14.5.2003
Где: Корусант

Репутация: 20
Всего: 329



Цитата(Alam @  16.3.2006,  17:46 Найти цитируемый пост)
и тригер получается амбарный 

ничего страшного, у меня не 100, конечно, но 50 было, зато 1 раз сделал и порядок, я думаю, что можно ещё и оргинизовать цикл по записям системных таблиц, где хранятся имена таблиц и полей. Тебе нужно найти только как называются системные таблицы. IBExpert тебе в руки. 
PM MAIL   Вверх
vv3
Дата 7.5.2006, 01:00 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 75
Регистрация: 29.4.2006

Репутация: нет
Всего: нет



Вот эскиз штуки, которая тебе может помочь - генерирует триггер автоматически при добавлении поля в таблицу. Разумеется LOG_таблицы должны быть созданы предварительно.

Код

CREATE TRIGGER RDB$RELATION_FIELDS_AID0 FOR RDB$RELATION_FIELDS
ACTIVE AFTER INSERT POSITION 99
AS
DECLARE VARIABLE TMPFIELD VARCHAR(31);
DECLARE VARIABLE AINSERT VARCHAR(16384);
DECLARE VARIABLE TABLENAME VARCHAR(31);
BEGIN
AINSERT = '';
TABLENAME = RTRIM(NEW.RDB$RELATION_NAME);

FOR SELECT RTRIM(F.RDB$FIELD_NAME)
    FROM RDB$RELATION_FIELDS F
    WHERE F.RDB$RELATION_NAME = :TABLENAME INTO :TMPFIELD DO
    BEGIN
        AINSERT = AINSERT ||
          'IF (NEW.' || :TMPFIELD || ' <> OLD.' || :TMPFIELD ||
          ') THEN INSERT INTO LOG_' || :TABLENAME || '(FIELD_NAME, OLD_VALUE, NEW_VALUE)
 VALUES(''' || :TMPFIELD || ''', OLD.' || :TMPFIELD || ', NEW.' || :TMPFIELD || ');
 ';
       END
       IF (NOT EXISTS(SELECT T.RDB$TRIGGER_NAME
                FROM RDB$TRIGGERS T
                WHERE T.RDB$TRIGGER_NAME = 'LOG_' || :TABLENAME)) THEN

    EXECUTE STATEMENT
    'CREATE TRIGGER LOG_' || :TABLENAME || ' FOR ' || :TABLENAME || '
 ACTIVE AFTER UPDATE POSITION 99
 AS
 BEGIN
   ' || :AINSERT || '
 END';
    ELSE
    EXECUTE STATEMENT
    'ALTER TRIGGER LOG_' || :TABLENAME || ' ACTIVE AFTER UPDATE POSITION 99
 AS
 BEGIN
   ' || :AINSERT || '
 END';

END

 
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Interbase"
Alex

Обязательно указание:

1. Версию InterBase (Firebird, Yaffil)

2. Способа доступа (ADO, BDE, IBX и т.д.)

  • КАК ПРАВИЛЬНО ОФОРМИТЬ КОД - ЗДЕСЬ
  • КАК ПРАВИЛЬНО УКАЗАТЬ ТЕКСТ ОШИБКИ - ЗДЕСЬ
  • Действия модераторов можно обсудить здесь
  • С просьбами о написании курсовой, реферата и т.п. обращаться сюда
  • FAQ раздела лежит здесь!

Если Вам понравилась атмосфера форума, заходите к нам чаще! С Уважением, Akella.

 
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Firebird, Interbase | Следующая тема »


 




[ Время генерации скрипта: 0.1244 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.