|
Триггер AFTER UPDATE срабатывает не всегда
|
|||
---|---|---|---|
#18+
Пишу триггер для Cache на обычном SQL. Таблица: Код: sql 1. 2. 3. 4. 5.
Триггер: Код: sql 1. 2. 3. 4. 5. 6. 7.
Поле ENTITY1_COND используется для выбора какого-либо действия над данными внутри тела триггера: если ENTITY1_COND = 0, выполняется одно действие, если ENTITY1_COND = 1 выполняется другое действие. Проблема в том, что триггер срабатывает только тогда, когда новое значение ENTITY1_COND отличается от старого значения. Если же при выполнении команды UPDATE старое и новое значение ENTITY1_COND совпадают, то триггер вообще не вызывается: Код: sql 1. 2.
При выполнении второй команды триггер не работает. Это большая проблема для меня: данный триггер использовался для разных СУБД (SQL Server, Oracle, Firebird, MySQL), и нигде я не припомню такого. В других СУБД триггер всегда срабатывает, если в команде UPDATE присваивается значение полю ENTITY1_COND; и неважно, совпадают старое и новое значения или нет. Может быть, я что-то неправильно понял? Как в Cache добиться того, чтобы триггер на UPDATE всегда срабатывал? ... |
|||
:
Нравится:
Не нравится:
|
|||
24.01.2013, 17:42 |
|
Триггер AFTER UPDATE срабатывает не всегда
|
|||
---|---|---|---|
#18+
crossa , Как Вы узнали, что триггер именно не сработал, а не произошла, например, ошибка? Код триггера у Вас написан на T-SQL, но, к сожалению, не указан сам код. Был уже вопрос, похожий на Ваш: 12992239 Сделал небольшой тест:Class del.c Extends %Persistent [ SqlTableName = ENTITY1 ] { Property SText As %String(MAXLEN = 100) [ SqlFieldName = STEXT ]; Property Entity1Cond As %Char [ SqlFieldName = ENTITY1_COND ]; ClassMethod Fill() { do ..%KillExtent() &sql(insert into ENTITY1(STEXT,ENTITY1_COND)values('ZZZ','1')) &sql(update ENTITY1 set STEXT='DDD',ENTITY1_COND='1' where id=1) } Trigger NewTrigger1 [ Event = UPDATE, Foreach = row, SqlName = ENTITY1_TR, Time = AFTER, UpdateColumnList = Entity1Cond ] { set ^tmp("ENTITY1_COND новое")={ENTITY1_COND*N} set ^tmp("ENTITY1_COND старое")={ENTITY1_COND*O} set ^tmp("ENTITY1_COND старое и новое отличаются?")=$s({ENTITY1_COND*C}:"Да",1:"Нет") set ^tmp("STEXT новое")={STEXT*N} set ^tmp("STEXT старое")={STEXT*O} set ^tmp("STEXT старое и новое отличаются?")=$s({STEXT*C}:"Да",1:"Нет") } }Результат: Код: plaintext 1. 2. 3. 4. 5. 6.
... |
|||
:
Нравится:
Не нравится:
|
|||
24.01.2013, 18:40 |
|
Триггер AFTER UPDATE срабатывает не всегда
|
|||
---|---|---|---|
#18+
servit Спасибо за ответ. Мой программный продукт работает с разными типами СУБД, генерит SQL-запросы на создание таблиц, триггеров, индексов, внешних ключей и т.д. Не хотелось бы ради одной лишь Cache писать триггеры на ObjectScript вместо T-SQL; это затруднит модификацию шаблонов SQL-запросов в будущем для моих коллег, кто не имела дела с СУБД Cache. Версия Cache: Cache for Windows (x86-32) 2012.2.1 (Build 705.0U_SU), демо-версия. Моя программа подключается к базе данных через драйвер ODBC; если бы были какие-то ошибки при выполнении триггера, программа получила об этом сообщение. Проверил, в каком виде мои триггеры хранятся в базе Cache в виде ObjectScript. Параметр UpdateColumnList в заголовке триггера отсутствует, хотя в SQL-запросе на создание триггера явно указано, что он срабатывает при изменении поля ENTITY1_COND. Вместо это добавилась первая команда в теле триггера, которую я в исходном SQL-запросе не прописывал: Trigger ENTITY1TR2 [ Event = UPDATE, Foreach = ROW, Language = cache, NewTable = NEW_ENTITY1, OldTable = OLD_ENTITY1, Order = 1, SqlName = ENTITY1_TR2, Time = AFTER ] { If '({ENTITY1_COND*C}) Quit // From UPDATE OF field list Насколько я понимаю, именно поэтому триггер не срабатывает для тех случаев, когда старое и новое значение ENTITY1_COND совпадают. Может быть, дело в символе подчеркивания в названии поля ENTITY1_COND? Как я заметил, Cache очень "нервно" реагирует на имена идентификаторов, где есть этот символ. К сожалению, переименовать поле таблицы не могу, так как это служебное поле для всех видов СУБД. ... |
|||
:
Нравится:
Не нравится:
|
|||
25.01.2013, 15:34 |
|
Триггер AFTER UPDATE срабатывает не всегда
|
|||
---|---|---|---|
#18+
crossaНасколько я понимаю, именно поэтому триггер не срабатывает для тех случаев, когда старое и новое значение ENTITY1_COND совпадают.Всё верно, за это ответственна конструкция UPDATE OF ENTITY1_COND A trigger specified as UPDATE OF is executed only when one or more of the specified columns is updated in a row in the specified table.Если старое и новое значения совпадают, значит и обновления фактически нет. Тогда какой смысл в вызове триггера и в этой конструкции? crossaНе хотелось бы ради одной лишь Cache писать триггеры на ObjectScript вместо T-SQLИ не нужно. Оставьте триггер на SQL, но тогда уберите UPDATE OF ENTITY1_COND . Если Ваш триггер немного видоизменить:CREATE TRIGGER ENTITY1_TR AFTER UPDATE ON ENTITY1 REFERENCING OLD ROW AS OLD_ENTITY1 NEW ROW AS NEW_ENTITY1 FOR EACH ROW WHEN (OLD_ENTITY1.ENTITY1_COND!=NEW_ENTITY1.ENTITY1_COND) select 1,'bla-bla-bla' -- некий код, то работать будет так же. ... |
|||
:
Нравится:
Не нравится:
|
|||
25.01.2013, 17:23 |
|
Триггер AFTER UPDATE срабатывает не всегда
|
|||
---|---|---|---|
#18+
servitЕсли старое и новое значения совпадают, значит и обновления фактически нет. Тогда какой смысл в вызове триггера и в этой конструкции? Это поле - признак того, какая именно операция над данными была выполнена. Если в поле записывается "1", то триггер обрабатывает данные одним способом, если "2" - другим способом и т.д. В других СУБД (а их уже около десятка, включая, например, старые версии Informix) всё работало как надо. В других СУБД обновлением поля таблицы считается перезаписывание данных в этом поле, даже если новые данные совпадают со старыми. И только в СУБД Cache обновлением поля является изменение данных. Убрать UPDATE OF ENTITY1_COND - это не лучший выход, так как триггер может содержать действия и над самой таблицей, для которой создан триггер. Придется что-то изобретать. Спасибо за ответ. ... |
|||
:
Нравится:
Не нравится:
|
|||
26.01.2013, 02:27 |
|
|
start [/forum/topic.php?fid=39&tid=1557246]: |
0ms |
get settings: |
10ms |
get forum list: |
14ms |
check forum access: |
3ms |
check topic access: |
3ms |
track hit: |
189ms |
get topic data: |
11ms |
get forum data: |
2ms |
get page messages: |
39ms |
get tp. blocked users: |
1ms |
others: | 258ms |
total: | 530ms |
0 / 0 |