![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Ведение логов изменения некоторой величины [D7, Firebird]
Mr. D. © (2007-03-07 16:36:00)Допустим, есть таблица:
id | SomeField | SomeField_history
id - PK
SomeField - integer
SomeField_history - blob, где ведется лог изменения величины в колонке SomeField
Такой триггер имеем:
create trigger my_trig for "TestTable"
active after update position 0
as
declare variable insert_string blob;
begin
if ( old.SomeField <> new.SomeField ) then
begin
insert_string = 'LOG ' || CAST(new.SomeField as char);
UPDATE "TestTable" t set t.SomeField_history = :insert_string WHERE t.id = new.id;
end
end;
Но с этим тригером при изменении величины SomeField выдается ошибка:
Error Message:
----------------------------------------
Unsuccessful execution caused by a system error that precludes
successful execution of subsequent statements.
internal error.
[00542BAF]
Почему же так? :(
G_M_S (2007-03-12 17:42:00) [1]
new.STATUS_HISTORY = new.STATUS_HISTORY || 'Delive to ' || CAST(new.STATUS as char);
1) Поле BLOB должно иметь тип TEXT (кажись 2)
2) new.STATUS_HISTORY = old.STATUS_HISTORY||' '||CAST(new.STATUS as varchar(!длина!))
atruhin (2007-03-12 14:31:00) [2]Как использовать UDF и как писать есть на ibase, все очень просто.
> FreeUDFLib подойдет?
Смотри там описание есть. Неплохая библиотека, но я ее использую как пример функций,
для реализации того что нужно мне. Вообще серьезно работать с FB без UDF нереально,
ведь в нем потому так мало стандартных функций, что всегда можно дописать, что душе угодно.
А вообще подумай о
> [25] atruhin © (12.03.07 07:09)
Mr. D. (2007-03-12 13:40:00) [3]atruhin © (12.03.07 7:00) [23]
Ну дак он нормально пишет, что невозможно объеденить BLOB поле со строкой
а средствами SQL в триггерах этого никак не сделать?
atruhin © (12.03.07 7:02) [24]
Оно и сейчас недалеко, воспользуйся UDF, найди готовую или напиши.
я UDF никогда не пользовался, как подключать, как использовать... В какое хоть направление искать? UDF по работе с blob?
Например: http://www.ibase.ru/d_udf.htm
FreeUDFLib подойдет?
atruhin (2007-03-12 07:09:00) [4]Хотя кончно более правильным будет создать отдельную таблицу куде писать:
ID - измененого объекта, время изменения, кто изменил, что изменил.
Можно посмотреть как реализована история изменений в IBExpert, очень неплохо.
atruhin (2007-03-12 07:02:00) [5]> Счастье то так близко...
Оно и сейчас недалеко, воспользуйся UDF, найди готовую или напиши.
atruhin (2007-03-12 07:00:00) [6]Ну дак он нормально пишет, что невозможно объеденить BLOB поле со строкой.
Mr. D. (2007-03-12 03:40:00) [7]DrPass © (11.03.07 2:59) [21]
Злая клевета на триггеры, конечно. Естественно, триггер должен быть before update, а не after
да уж :( Действительно, в before надо было делать, а я делал в after... Но возникла проблема:
если рассмотреть такой триггер:
create trigger orders_status_history for "ORDERS"
active before update position 11
as
begin
if ( old.STATUS <> new.STATUS ) then
begin
new.STATUS_HISTORY = 'Delive to ' || CAST(new.STATUS as char);
end
end;
Все работает просто супер! Но вот мне нужно чтобы логи складывались, то есть чтобы была видна вся история изменения поля STATUS:
create trigger orders_status_history for "ORDERS"
active before update position 11
as
begin
if ( old.STATUS <> new.STATUS ) then
begin
new.STATUS_HISTORY = new.STATUS_HISTORY|| 'Delive to ' || CAST(new.STATUS as char);
end
end;
вот в этом случае уже выдается:
Error Message:
----------------------------------------
Overflow occurred during data type conversion.
conversion error from string "BLOB".
[00542BAF]
эх.. можно как-нибудь бороться? Счастье то так близко...
DrPass (2007-03-11 02:59:00) [8]
> В общем, по моим экспрементам выходит, что если UPDATE не
> затрагивает некое поле, то и new.[поле] это не будет действовать.
> ..
Злая клевета на триггеры, конечно. Естественно, триггер должен быть before update, а не after
Mr. D. (2007-03-11 02:54:00) [9]Johnmen © (11.03.07 1:22) [19]
Ты же префикс NEW не указал
Да, ошибся, с руки писал.
В общем, по моим экспрементам выходит, что если UPDATE не затрагивает некое поле, то и new.[поле] это не будет действовать... Не так все на самом деле? Странно тогда...
Johnmen (2007-03-11 01:22:00) [10]
> SomeField_history = 'bla';не произведет никакого эффекта.
Ты же префикс NEW не указал.
Mr. D. (2007-03-10 23:52:00) [11]Johnmen © (09.03.07 9:07) [14]
Почему же не возымеет-то?
DrPass © (09.03.07 17:25) [17]
Вообще-то это делается простым присваиванием new.blahblahblah=...
не знаю... Проведенный мной эксперименты показывают, как я уже говорил:
Mr. D. (08.03.07 2:44) [13]
так как в UPDATE вполне возможно это поле не задействовано, поэтому это не возымеет действия...
то есть, я когда экспериментировал, если в UPDATE затронуто некое поле, то ему можно сделать:
new.blabla = bla
но если например запрос:
UPDATE TestTable SET SomeField = 4
То в триггере присвоение:
SomeField_history = 'bla';
не произведет никакого эффекта. А вот если:
UPDATE TestTable SET SomeField = 4, SomeField_history="bla"
то тогда будет.
DrPass (2007-03-09 17:25:00) [12]
> ну а как же в триггере на апдейт изменить поле таблицы,
> для которой создан этот триггер?
Вообще-то это делается простым присваиванием new.blahblahblah=...
Sergey13 (2007-03-09 09:37:00) [13]> [0] Mr. D. (07.03.07 16:36)
А зачем в блобе вести лог? Почему не просто в 3 (4) полях дата - юзер - [старое значение-] новое значение?
Сергей М. (2007-03-09 09:32:00) [14]
> Что же делать?
Для случая с блобом без UDF не обойтись.
Johnmen (2007-03-09 09:07:00) [15]
> Mr. D. (08.03.07 02:44) [13]
> new.SomeField_history присвоить нельзя, так как
> в UPDATE вполне возможно это поле не задействовано, поэтому
> это не возымеет действия...
Почему же не возымеет-то?
Mr. D. (2007-03-08 02:44:00) [16]DrPass © (08.03.07 0:22) [12]
блин, ну а как же в триггере на апдейт изменить поле таблицы, для которой создан этот триггер?
new.SomeField_history присвоить нельзя, так как в UPDATE вполне возможно это поле не задействовано, поэтому это не возымеет действия...
Что же делать?
DrPass (2007-03-08 00:22:00) [17]
> Mr. D. (07.03.07 23:44) [11]
Первоисточник, естессно - Interbase Data Definition Guide, раздел Working with Triggers.
If a trigger performs an action that causes it to fire again—or fires another trigger that
performs an action that causes it to fire—an infinite loop results. For this reason, it is
important to ensure that a trigger’s actions never cause the trigger to fire, even
indirectly.
Нельзя, вопщем.
Mr. D. (2007-03-07 23:44:00) [18]DrPass © (07.03.07 22:42) [10]
Ну и что? А ты мануал читал?
какой мануал? В каком месте?
Если здесь косяк - подскажи, пожалуйста, в чем?
DrPass (2007-03-07 22:42:00) [19]
> Там же стоит условие:
>
> if (old.SomeField <> new.SomeField )
Ну и что? А ты мануал читал?
Johnmen (2007-03-07 22:31:00) [20]
> Mr. D. (07.03.07 22:18) [8]
Да-да, понятно...
Дело в blob, т.к. так апдейтить их нельзя. Как можно? А я не помню...:)
Читай ibase.ru Найдешь ответ - нам расскажешь...