Этот баннер — требование Роскомнадзора для исполнения 152 ФЗ.
«На сайте осуществляется обработка файлов cookie, необходимых для работы сайта, а также для анализа использования сайта и улучшения предоставляемых сервисов с использованием метрической программы Яндекс.Метрика. Продолжая использовать сайт, вы даёте согласие с использованием данных технологий».
Политика конфиденциальности
|
|
|
Объясните как сделать правельный триггер
|
|||
|---|---|---|---|
|
#18+
Есть таблицы в которых существует поле modify (timestamp without time zone) - это поле в которое записывается дата создания или изменения записи в таблицы. Это поле обновляется через триггер по INSERT или UPDATE. Тригер Код: plaintext 1. 2. 3. 4. Функция Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. Только вот проблема. Иногда нужно самому изменять значение этого поля. Пишу: Код: plaintext 1. Только вот это поле всеравно заменяется значением из тригера. Теперь вопрос. Где у меня ошибка. И поясните всетаки смысл AFTER и BEFORE. Я себе предстовлял это так что когда ставшь признак BEFORE то заполенеие происходит так: Сначало создается запись, потом срабатывает BEFORE и заполняет поля (вернее сам заполняешь в процедуре если надо), потом заполняются поля которые передал в INSERT потом срабатывает AFTER - который в свою очередь может заполнить даные (вернее сам заполняешь в процедуре если надо). А потом происходит запись данных. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 08.07.2008, 11:46 |
|
||
|
Объясните как сделать правельный триггер
|
|||
|---|---|---|---|
|
#18+
Код: plaintext Спросите у сервера Код: plaintext надо так. Код: plaintext ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 08.07.2008, 12:14 |
|
||
|
Объясните как сделать правельный триггер
|
|||
|---|---|---|---|
|
#18+
IF NEW.modify IS NULL THEN ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 08.07.2008, 12:15 |
|
||
|
Объясните как сделать правельный триггер
|
|||
|---|---|---|---|
|
#18+
Shagrat Код: plaintext 1. Ошибка здесь. Сравнение NULL с другими значениями всегда возвращает NULL. А NULL это и не True и не False. См. также IS NULL, Coalesce Shagrat Теперь вопрос. Где у меня ошибка. И поясните всетаки смысл AFTER и BEFORE. Я себе предстовлял это так что когда ставшь признак BEFORE то заполенеие происходит так: Сначало создается запись, потом срабатывает BEFORE и заполняет поля (вернее сам заполняешь в процедуре если надо), потом заполняются поля которые передал в INSERT потом срабатывает AFTER - который в свою очередь может заполнить даные (вернее сам заполняешь в процедуре если надо). А потом происходит запись данных. Слегка иначе... 0. Делаем INSERT/UPDATE 1. Подготавливается новый ROW нужного типа, для которого последовательно отрабатывают DEFAULT'ы. 2. ROW передается в триггеры BEFORE (в порядке наименований триггеров). Только в триггере BEFORE можно поменять строку и откатить INSERT/UPDATE вернув NULL. В AFTER такого не проканает. 3. Запускается проверка Constraint и т.д. для новой версии строки. 4. Запускается триггер AFTER, он уже не влияет на строку через NEW, зато можно быть уверенным, что если до сюда дошло, то строка будет добавлена в базу (разве вилку из розетки выдернут). Здесь можно откатить всю транзакцию RAISE EXCEPTION. 5. Если до сюда дошло, то версия строки еще после нескольких преобразований попадает в базу. Но это еще более отдельная песня. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 08.07.2008, 12:28 |
|
||
|
Объясните как сделать правельный триггер
|
|||
|---|---|---|---|
|
#18+
Теперь становиться ясно (алгоритм примерно я так и представлял). Только вот всеравно не работает. Когда меняешь другое поле триггер теперь не срабатывает. Странно. Код: plaintext 1. Дата не обновляется, а если изменять поле то изменяется. Вот полные исходники: Код: 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. Подскажите ка всетаки это оживить. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 08.07.2008, 12:41 |
|
||
|
Объясните как сделать правельный триггер
|
|||
|---|---|---|---|
|
#18+
Может быть 'modify' - зарезервированнное слово. Возьми его везде в кавычки NEW.'modify' ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 08.07.2008, 13:09 |
|
||
|
Объясните как сделать правельный триггер
|
|||
|---|---|---|---|
|
#18+
MySQLCraftМожет быть 'modify' - зарезервированнное слово. Возьми его везде в кавычки NEW.'modify'в SQL одинарные кавычки означают строковую константу. в pg используются двойные кавычки для экранирования идентификаторов. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 08.07.2008, 13:28 |
|
||
|
Объясните как сделать правельный триггер
|
|||
|---|---|---|---|
|
#18+
ShagratТеперь становиться ясно (алгоритм примерно я так и представлял). Только вот всеравно не работает. Когда меняешь другое поле триггер теперь не срабатывает. Странно. Код: plaintext 1. Дата не обновляется, а если изменять поле то изменяется. Вот полные исходники: Код: 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. Подскажите ка всетаки это оживить. гыгы. еслиб в том месте, где работает триггер было бы действительно Код: plaintext Код: plaintext Код: plaintext можно проверять Код: plaintext Код: plaintext ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 08.07.2008, 13:29 |
|
||
|
Объясните как сделать правельный триггер
|
|||
|---|---|---|---|
|
#18+
ShagratТеперь становиться ясно (алгоритм примерно я так и представлял). Только вот всеравно не работает. Когда меняешь другое поле триггер теперь не срабатывает. Странно.ничего странного, имхо у Вас проблема с логикой Вашего алгоритма. Попробуйте переформулировать задачу, абсолютно точно и подробно написать что именно Вы хотите что бы происходило :) например типа такого: если вставляется новая запись с полем modify is null, то .... если вставляется новая запись с полем modify > текущей даты, то ... если вставляется новая запись с полем modify <= текущей даты, то ... если обновляется запись в которой старое значение поля modify is null и новое значение поля modify is null, то ... и так далее. тогда Вам имхо проще будет понять в чём у Вас проблема. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 08.07.2008, 13:38 |
|
||
|
Объясните как сделать правельный триггер
|
|||
|---|---|---|---|
|
#18+
Все просто. Если вставляю или обновляю поле, без modify то дата ставится текущая сервера (тоесть триггером). Если я сам прописываю в запросе поле modify то данные берутся из него. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 08.07.2008, 14:12 |
|
||
|
Объясните как сделать правельный триггер
|
|||
|---|---|---|---|
|
#18+
4321 Код: plaintext Код: plaintext Не получится. У него триггер на INSERT/UPDATE. OLD для INSERT не определен. Надо разгребать 2 ситуации. TG_OP = 'INSERT' AND NEW.Modify IS NULL и TG_OP = 'UPDATE' AND Coalesce(NEW.Modify != OLD.Modify, True) Как-то так. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 08.07.2008, 14:17 |
|
||
|
Объясните как сделать правельный триггер
|
|||
|---|---|---|---|
|
#18+
Все это можно но я не пойму почему просто Код: plaintext нельзя поставить, при этом все условия и так выполняется. Данные передаваемые запросом, должны заполниться всеравно после AFTER. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 08.07.2008, 14:25 |
|
||
|
Объясните как сделать правельный триггер
|
|||
|---|---|---|---|
|
#18+
ShagratВсе просто. Если вставляю или обновляю поле, без modify то дата ставится текущая сервера (тоесть триггером). Если я сам прописываю в запросе поле modify то данные берутся из него. Вы ошибочно полагаете что не указанные в запросе обновления поля принимают значение null в тригере в псевдозаписе NEW, но это не так. не указанные в запросе поля заполняются _старыми_ значениями, поэтому Ваше условие "if new.modify is null then" сработает при обновлении только один раз - если у обновляемой записи в базе поле modify равно null. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 08.07.2008, 14:52 |
|
||
|
Объясните как сделать правельный триггер
|
|||
|---|---|---|---|
|
#18+
Я понимаю что значение принимается старое. Мне непонятен другой факт. Последовательность присвоения значения. Я полагаю что если вызов AFTER то это означает что событие возникнет перед заполнением полей из самого запроса. Тоесть: 1. Поле заполняется старым значением 2. Вызов AFTER- в моем случаи заполнение в триггере (Достаточно без условий, простое присвоение) 3. Заполнение данными из самого запроса. 4. событие BEFORE (Как я понял там возможна только проверка данных). 5. Ну м сама запись данных в поле (Не учитываю транзакции, кеши, блокировки итд.) Так вот вопрос почему, при запросе без поля modify данные, изменяет триггер. А при запросе с modify также данные заполняет триггер - но после не прописываются данные с самого запроса, а остаются триггерные. Получается триггер AFTER вызывается после заполнения данных самим запросом. Тогда непонятно как сделать чтобы всетаки происходило по алгоритму описанному выше. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 08.07.2008, 15:49 |
|
||
|
Объясните как сделать правельный триггер
|
|||
|---|---|---|---|
|
#18+
ShagratМне непонятен другой факт. Последовательность присвоения значения. Я полагаю что если вызов AFTER то это означает что событие возникнет перед заполнением полей из самого запроса. Тоесть: 1. Поле заполняется старым значением 2. Вызов AFTER- в моем случаи заполнение в триггере (Достаточно без условий, простое присвоение) 3. Заполнение данными из самого запроса. 4. событие BEFORE (Как я понял там возможна только проверка данных). 5. Ну м сама запись данных в поле (Не учитываю транзакции, кеши, блокировки итд.)брр... у Вас видимо описка и вместо AFTER следует читать BEFORE, а вместо BEFORE - AFTER ? :) у Вас конкретно всё перепутано :) должно быть имхо вот так: 1. Поле заполняется старым значением 3. Заполнение данными из самого запроса. 2. Вызов BEFORE - в моем случаи заполнение в триггере (Достаточно без условий, простое присвоение) 5. Ну м сама запись данных в поле (Не учитываю транзакции, кеши, блокировки итд.) 4. событие AFTER (Как я понял там возможна только проверка данных). -- можно update делать, только главное не зациклиться :) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 08.07.2008, 16:26 |
|
||
|
Объясните как сделать правельный триггер
|
|||
|---|---|---|---|
|
#18+
BEFORE (ПЕРЕД) и AFTER (ПОСЛЕ) - это относительно внесения изменений в таблицу, а не относительно получения данных из запроса. в тригере BEFORE таблица _ещё не изменена_, в тригере AFTER - таблица _уже изменена_ -- „Истина — это вовсе не то, что можно убедительно доказать, это то, что делает всё проще и понятнее“ — Антуан де Сент-Экзюпери ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 08.07.2008, 16:31 |
|
||
|
Объясните как сделать правельный триггер
|
|||
|---|---|---|---|
|
#18+
Ой извините, напутал, Я так и и мел ввиду. По логике я все правильно понимаю. Так вот у меня и не работает. Эта логика Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. Когда делаешь: Код: plaintext Когда делаешь: Код: plaintext По вашей схеме логике видно что сначало обрабатываются данные с запроса, а потом вызывается BEFORE - тогда понятно почему не работает. Так всетаки получается ваша схема является правильной. - Если да то тогда действительно придется сравнивать старые данные данные. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 08.07.2008, 16:41 |
|
||
|
Объясните как сделать правельный триггер
|
|||
|---|---|---|---|
|
#18+
А не проще DEFAULT=now() определить и не париться с триггерами? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 08.07.2008, 18:19 |
|
||
|
Объясните как сделать правельный триггер
|
|||
|---|---|---|---|
|
#18+
DEFAULT now() без равно ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 08.07.2008, 18:20 |
|
||
|
Объясните как сделать правельный триггер
|
|||
|---|---|---|---|
|
#18+
MySQLCraftDEFAULT now() без равнодефолт не прокатит. на апдейт автору тоже надо модифачить. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 08.07.2008, 18:54 |
|
||
|
Объясните как сделать правельный триггер
|
|||
|---|---|---|---|
|
#18+
4321 MySQLCraftDEFAULT now() без равнодефолт не прокатит. на апдейт автору тоже надо модифачить. SET modify = NULL Пожертвовать удобством ради скорости и простоты ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 08.07.2008, 18:56 |
|
||
|
Объясните как сделать правельный триггер
|
|||
|---|---|---|---|
|
#18+
Нет. Потомучто я могу его сменить. А мне нужно чтобы оно менялось после каждого INSERT или UPDATE ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 08.07.2008, 18:56 |
|
||
|
Объясните как сделать правельный триггер
|
|||
|---|---|---|---|
|
#18+
MySQLCraft 4321 MySQLCraftDEFAULT now() без равнодефолт не прокатит. на апдейт автору тоже надо модифачить. SET modify = NULL Пожертвовать удобством ради скорости и простотыSET modify = NULL запишет в modify null, а не default. что бы был default нужно так и писать: set modify = default ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 08.07.2008, 19:10 |
|
||
|
Объясните как сделать правельный триггер
|
|||
|---|---|---|---|
|
#18+
Ёшчто бы был default нужно так и писать: set modify = default Точно! Забыл. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 09.07.2008, 00:37 |
|
||
|
Объясните как сделать правельный триггер
|
|||
|---|---|---|---|
|
#18+
ShagratНет. Потомучто я могу его сменить. А мне нужно чтобы оно менялось после каждого INSERT или UPDATE Зачем "после", когда можно "во время"? Во время INSERT будет установлено ваше значение либо автоматически значение по дефолту. Во время UPDATE Вам придется каждый раз добавлять в выражение , modify = default или ваше значение. Если Вам это трудно или Вы не доверяете своей программе или пользователям нужно иметь доступ для прямого UPDATE и при этом таблица должна сама себя мониторить тогда извините. Так ли это необходимо? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 09.07.2008, 00:50 |
|
||
|
Объясните как сделать правельный триггер
|
|||
|---|---|---|---|
|
#18+
MySQLCraftТак ли это необходимо?Это логично. Всю логику, связанную с базой поместить в базу. Мало ли - сегодня у нас один клиент, а завтра ещё будет. И нужно везде не забыть про это поле? Нет уж, целостность и корректность данных нужно максимально отдавать на откуп базе. В идеале (если идеал этот достижим) клиент является лишь оболочкой, ничего не вычисляющей, но лишь принимающей данные от пользователя и возвращающие ему ответ. Но это идеал, конечно в реальности что-то клиент вычисляет. Но, повторюсь, такие вещи как целостность и непротиворечивость данных надо отдать БД. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 09.07.2008, 01:36 |
|
||
|
Объясните как сделать правельный триггер
|
|||
|---|---|---|---|
|
#18+
pamir MySQLCraftТак ли это необходимо?Это логично. Всю логику, связанную с базой поместить в базу. Мало ли - сегодня у нас один клиент, а завтра ещё будет. И нужно везде не забыть про это поле? Нет уж, целостность и корректность данных нужно максимально отдавать на откуп базе. В идеале (если идеал этот достижим) клиент является лишь оболочкой, ничего не вычисляющей, но лишь принимающей данные от пользователя и возвращающие ему ответ. Но это идеал, конечно в реальности что-то клиент вычисляет. Но, повторюсь, такие вещи как целостность и непротиворечивость данных надо отдать БД. Для доступа к таблицам можно использовать представления, процедуры, функции, а для целостности внешние ключи и прочие ограничения. Зачем юзеру прямой доступ к таблицам, чтобы он имел возможность одним запросом положить сервер или грохнуть все данные? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 09.07.2008, 09:58 |
|
||
|
Объясните как сделать правельный триггер
|
|||
|---|---|---|---|
|
#18+
к томуже врядли время апдейта используется для поддержания целостности, скорее для мониторинга. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 09.07.2008, 10:03 |
|
||
|
Объясните как сделать правельный триггер
|
|||
|---|---|---|---|
|
#18+
наверное в чистом виде такого поведения, чтобы при вставке/апдейте с SET моеполе = блаблабла вставлялось всегда и именно блаблабла а без - всегда в т.ч. апдейтилось на default добиться нельзя (можно с точностью до того, что когда и если Код: plaintext однако можно чтобы _всегда_ апдейтилось на дефолт, а для ручной правки с помощью скл-стейтмента сделать в триггере TG_ARGV[], для чего вести скажем служебную табличку с одной записью==полем==переменной. И такой апдейт делать в транзакции (или в спец хп) Код: plaintext 1. 2. 3. 4. как юзать TG_ARGV[], читать здесь Триггер с параметрами ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 09.07.2008, 10:49 |
|
||
|
Объясните как сделать правельный триггер
|
|||
|---|---|---|---|
|
#18+
В моем проекте это поле нужно для возможности синхронизировать 2 базы. 1. Тоесть клиентская программа это поле не меняет, его меняет сама база. 2. Есть другая программа, которая по уникальному полю определяет новые записи, а по дате определяет измененные. И синхронизирует таблицы. Потому и возникает такая проблема что у клиента все нормально изменяется, а программа синхронизации не удается сменить это поле, из-за неправильной работы триггера. Сразу говорю, что кластера не предлагать, потому что эти две базы могут быть долгое время не в online. И всякие стандартные методы синхронизации тоже не подойдут, потомучто у синхронизатора слишком сложный алгоритм принятия решения о направлении синхронизации, и обновляемых данных. P.S Насчет делать обработку на стороне клиента (или синхронизатора). Это действительно не очень хорошый вариант. 1. Время на клиенте может стоять неверное (что встречалось нечасто). Можно конечно и применять функцию now() в запросе. 2. Так как таблиц таких многовато, то есть вероятность гдето в программе клиента забыть про это поле тем самым испортить актуальные данные при синхронизации баз (Что недопустимо). 3. Количество таблиц все время меняется. Создаются динамически по требованию. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 09.07.2008, 11:02 |
|
||
|
Объясните как сделать правельный триггер
|
|||
|---|---|---|---|
|
#18+
ну так сам бог велел ваш "синхронизатор" запущать в отдельной транзакции/сессии со сменой всего одной "переменной сессии" (под переменной сессии может подразумеваться любой временный объект, существующий либо только внутри транзакции, либо внутри сессии). и тогда вам надо только поменять триггерную ф-ю на параметрическую, и процедуру старта "синхронизатора" (если тот держит одну сессию) - устанавливать там ту самую "переменную сессии". Но если "синхронизатор" ваш коннектится внутри сеанса своей работы много и безсистемно (т.е. создает массу разных сеансов на сервере бд), - придется поменять все вызовы апдейта из синхронизатора (перед каждым апдейтом устанавливать "переменную сессии"), или все места установления начала сессии-соединения. Т.е. возможно - несколько мест. а не одно. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 09.07.2008, 11:27 |
|
||
|
Объясните как сделать правельный триггер
|
|||
|---|---|---|---|
|
#18+
MySQLCraftДля доступа к таблицам можно использовать представления, процедуры, функции, Да, можно MySQLCraftа для целостности внешние ключи и прочие ограничения. Естественно MySQLCraftЗачем юзеру прямой доступ к таблицам, чтобы он имел возможность одним запросом положить сервер или грохнуть все данные?Про прямой доступ юзерам никто не говорил. Я отвечал на: MySQLCraftВо время UPDATE Вам придется каждый раз добавлять в выражение , modify = default или ваше значение. Если Вам это трудно или Вы не доверяете своей программе Зачем отдавать это клиентскому приложению, когда логичнее именно на триггерах или ещё как-то, но на стороне БД, поддерживать это поле. К тому же, своей программе можно доверять, но завтра проект вырос и к таблице обращается ещё одна программа, написанная другими (другим отделом, другой группой в отделе - как угодно). А им забыли сообщить об этой особенности. Так нафига эти проблемы, когда поместив всю логику на сторону сервера, вы их избегаете. И при любой модификации логики (мало ли, нужно ставить не текущую дату, а дату на час меньше или больше) вам не нужно переписывать каждую программу или множество мест в программе - вы переписываете только серверную часть. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 09.07.2008, 11:44 |
|
||
|
Объясните как сделать правельный триггер
|
|||
|---|---|---|---|
|
#18+
Да дискуссия затянулась. А можно реальный пример реализации. Если можно то рабочий. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 09.07.2008, 11:54 |
|
||
|
Объясните как сделать правельный триггер
|
|||
|---|---|---|---|
|
#18+
ShagratДа дискуссия затянулась. А можно реальный пример реализации. Если можно то рабочий.чего ж реальней то Код: 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. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 09.07.2008, 12:06 |
|
||
|
Объясните как сделать правельный триггер
|
|||
|---|---|---|---|
|
#18+
ShagratА можно реальный пример реализации. Если можно то рабочий.зы лудше писадь таг: автор"а можно примерный пример реальной реализации" ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 09.07.2008, 12:08 |
|
||
|
Объясните как сделать правельный триггер
|
|||
|---|---|---|---|
|
#18+
Не стоит придираться к словам Ж). Может есть способ увидеть данные переданные в запросе. И в зависимости от них брать дату из запроса, или ставить свою ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 09.07.2008, 12:21 |
|
||
|
Объясните как сделать правельный триггер
|
|||
|---|---|---|---|
|
#18+
ShagratМожет есть способ увидеть данные переданные в запросе. И в зависимости от них брать дату из запроса, или ставить свою добраться из триггерной фунции можно сюда авторWhen a PL/pgSQL function is called as a trigger, several special variables are created automatically in the top-level block. They are: NEW Data type RECORD; variable holding the new database row for INSERT/UPDATE operations in row-level triggers. This variable is NULL in statement-level triggers. OLD Data type RECORD; variable holding the old database row for UPDATE/DELETE operations in row-level triggers. This variable is NULL in statement-level triggers. TG_NAME Data type name; variable that contains the name of the trigger actually fired. TG_WHEN Data type text; a string of either BEFORE or AFTER depending on the trigger's definition. TG_LEVEL Data type text; a string of either ROW or STATEMENT depending on the trigger's definition. TG_OP Data type text; a string of INSERT, UPDATE, or DELETE telling for which operation the trigger was fired. TG_RELID Data type oid; the object ID of the table that caused the trigger invocation. TG_RELNAME Data type name; the name of the table that caused the trigger invocation. TG_NARGS Data type integer; the number of arguments given to the trigger procedure in the CREATE TRIGGER statement. TG_ARGV[] Data type array of text; the arguments from the CREATE TRIGGER statement. The index counts from 0. Invalid indices (less than 0 or greater than or equal to tg_nargs) result in a null value. как видим - никаких TG_SETS[] и т.п аналогов там не наблюдается. ДУмаю - приведенный набор рулящих пимпочек триггера исчерпывающий. Т.ч. либо вместо инсерт/апдейта пишите свои хп с полным перечнем и модифачьте поведение базы как требуется, либо придумывайте иной велосипед. (скажем -перехватывать текст стейтмента до его выполнения сервером и само-парсить в свой набор переменных сессии/транзакции. или, на худой, реализуйте вызов всех стейтментов из ваших прилад через экзекютирующую их ХП. но с предпарсингом (перед вызовом EXECUTE) строки передаваемого стейтмента в набор переменных. Иде Я: Кстати, попробуйте написать DO INSTEAD RULE подменяющую вставку/апдейт в таблицу с дефолтами, на вставку/апдейт в таблицу _без_ дефолтов, а там проверьте, что придет вместо NEW - набор данных из апдейтируемой записи подменённой , или подменяющей таблицы. Вряд ли, предвкушаю, найдется дырка, но "а вдруг"?) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 09.07.2008, 12:42 |
|
||
|
Объясните как сделать правельный триггер
|
|||
|---|---|---|---|
|
#18+
а так - ну попробуйте пользоваться ф-ей с одной дыркой в логике: Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 09.07.2008, 12:54 |
|
||
|
Объясните как сделать правельный триггер
|
|||
|---|---|---|---|
|
#18+
Я на этом и думал остановиться. Но к сожалению ваш пример почемуто не работает. ПОЧЕМУТО :( ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 09.07.2008, 13:10 |
|
||
|
Объясните как сделать правельный триггер
|
|||
|---|---|---|---|
|
#18+
ShagratЯ на этом и думал остановиться. Но к сожалению ваш пример почемуто не работает. ПОЧЕМУТО :(рискну предположить, у Вас есть записи созданые до написания этого тригера и в них modify равен null. из-за этого при их модификации условие "IF NEW.modify = OLD.modify THEN" не выполниться и поле modify изменено не будет. добавьте отладочный вывод - тогда будет понятно что происходит, например так: Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 09.07.2008, 14:29 |
|
||
|
Объясните как сделать правельный триггер
|
|||
|---|---|---|---|
|
#18+
Спасибо за подсказку про отладку. (postgres - изучаю недавно) Все работает, если не выполнять один и тотже UPDATE Всетаки придется делать через переменные в триггере. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 09.07.2008, 15:07 |
|
||
|
Объясните как сделать правельный триггер
|
|||
|---|---|---|---|
|
#18+
pamirЗачем отдавать это клиентскому приложению, когда логичнее именно на триггерах или ещё как-то, но на стороне БД, поддерживать это поле. К тому же, своей программе можно доверять, но завтра проект вырос и к таблице обращается ещё одна программа, написанная другими (другим отделом, другой группой в отделе - как угодно). А им забыли сообщить об этой особенности. Так нафига эти проблемы, когда поместив всю логику на сторону сервера, вы их избегаете. И при любой модификации логики (мало ли, нужно ставить не текущую дату, а дату на час меньше или больше) вам не нужно переписывать каждую программу или множество мест в программе - вы переписываете только серверную часть. Извиняюсь. Я неправильно выразился, Вы неправильно поняли. "Программе" в смысле хранимой процедуре или функции. Так и понимать везде во всех моих мостах в этой теме. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 09.07.2008, 16:20 |
|
||
|
Объясните как сделать правельный триггер
|
|||
|---|---|---|---|
|
#18+
Код: plaintext надо поменять либо на Код: plaintext 1. 2. Код: plaintext но это, как уже предупреждалось, не спасет ситуацию при совпадении (т.е. ,в частности, при повторном запуске апдейта с прописанным SET mofify=xxxxx) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 09.07.2008, 16:23 |
|
||
|
Объясните как сделать правельный триггер
|
|||
|---|---|---|---|
|
#18+
... постах.... И всё таки, необходимость в такого рода тринггерах может появится только если пользователь имеет прямой доступ на UPDATE к таблице либо когда в процедуре или функции допускается изменение пользователем(не админом) даты обновления. Если юзер не имеет такого доступа, то триггер это лишнее звено. К чему я и веду. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 09.07.2008, 16:32 |
|
||
|
|

start [/forum/topic.php?all=1&fid=53&tid=2004227]: |
0ms |
get settings: |
6ms |
get forum list: |
11ms |
check forum access: |
2ms |
check topic access: |
2ms |
track hit: |
37ms |
get topic data: |
8ms |
get forum data: |
2ms |
get page messages: |
46ms |
get tp. blocked users: |
1ms |
| others: | 212ms |
| total: | 327ms |

| 0 / 0 |
