Этот баннер — требование Роскомнадзора для исполнения 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 |
|
||
|
|

start [/forum/topic.php?fid=53&msg=35418217&tid=2004227]: |
0ms |
get settings: |
10ms |
get forum list: |
17ms |
check forum access: |
3ms |
check topic access: |
3ms |
track hit: |
44ms |
get topic data: |
11ms |
get forum data: |
3ms |
get page messages: |
68ms |
get tp. blocked users: |
2ms |
| others: | 235ms |
| total: | 396ms |

| 0 / 0 |
