|
|
|
ALTER TABLE из TRIGGER
|
|||
|---|---|---|---|
|
#18+
Добрый день, уважаемые знатоки. Вопрос с подобным заголовком уже звучал на этом форуме, но проблемы там были другие. Моя в следующем. Имеется триггерная функция: Код: plsql 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. При этом: Код: sql 1. выдает, как и положено, одну строку с названием поля, которое имеется в таблице (и именуется fio). Но, при всем при том, что поле там одно и других нет точно, выполнение следующего кода Код: sql 1. вызывает ошибку: Код: plsql 1. 2. 3. 4. 5. 6. 7. 8. 9. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 07.04.2016, 09:04 |
|
||
|
ALTER TABLE из TRIGGER
|
|||
|---|---|---|---|
|
#18+
KraG, Код: sql 1. 2. 3. 4. 5. Точно нету? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 07.04.2016, 09:14 |
|
||
|
ALTER TABLE из TRIGGER
|
|||
|---|---|---|---|
|
#18+
Код: vbnet 1. 2. 3. 4. 5. 6. 7. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 07.04.2016, 09:20 |
|
||
|
ALTER TABLE из TRIGGER
|
|||
|---|---|---|---|
|
#18+
KraG Но, при всем при том, что поле там одно и других нет точно, выполнение следующего кода Код: sql 1. Сколько раз выполняли этот код? Для полной уверенности проверьте наличие поля в самом триггере. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 07.04.2016, 09:26 |
|
||
|
ALTER TABLE из TRIGGER
|
|||
|---|---|---|---|
|
#18+
авторСколько раз выполняли этот код? Ну, скажем, не сразу после первой неудачи стал писать на форум. Если я правильно понял вопрос. авторДля полной уверенности проверьте наличие поля в самом триггере. Какого поля? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 07.04.2016, 09:32 |
|
||
|
ALTER TABLE из TRIGGER
|
|||
|---|---|---|---|
|
#18+
KraGавторДля полной уверенности проверьте наличие поля в самом триггере. Какого поля? В триггере, перед безусловным добавлением поля в таблицу, явно проверьте наличие такого. P.S. У меня не очень хорошие чувства от системы, в которой поля в таблицы добавляются динамически. Точно нельзя сделать иначе? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 07.04.2016, 09:39 |
|
||
|
ALTER TABLE из TRIGGER
|
|||
|---|---|---|---|
|
#18+
Господа, первоначальный вопрос снимается. Решил на всякий случай показать код создания триггера... Код: sql 1. 2. 3. Но, перед этим проверить иные варианты. И вот при таком выполнение происходит без ошибок. Код: sql 1. 2. 3. Теперь мой вопрос - почему так то? Ткните, пожалуйста, в кучку ссылок или тут объясните недалекому. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 07.04.2016, 09:41 |
|
||
|
ALTER TABLE из TRIGGER
|
|||
|---|---|---|---|
|
#18+
KraG, Вы действительно не понимаете — почему? При добавлении новой записи соответствующей колонки нет и всё работает нормально. Когда колонка изменяется (или ещё круче удаляется), вы зачем-то пытаетесь добавить это поле ещё раз. В целом же — вместо извращений с динамическим созданием колонок, вам просто нужна подчинённая таблица (Внешний Ключ + набор пермиссий). Посмотрите на что-то готовое. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 07.04.2016, 09:56 |
|
||
|
ALTER TABLE из TRIGGER
|
|||
|---|---|---|---|
|
#18+
vyegorovKraG, Вы действительно не понимаете — почему? При добавлении новой записи соответствующей колонки нет и всё работает нормально. Когда колонка изменяется (или ещё круче удаляется), вы зачем-то пытаетесь добавить это поле ещё раз. В целом же — вместо извращений с динамическим созданием колонок, вам просто нужна подчинённая таблица (Внешний Ключ + набор пермиссий). Посмотрите на что-то готовое. Любезный vyegorov, я действительно не понимаю почему одна и также триггерная функция при одном и том же событии (INSERT), но, в одном случае призванная реагировать только INSERT, а в другом и на другие события (UPDATE or DELETE), функционирует по-разному. Функционал для обработки UPDATE и DELETE я просто не дописал, ибо на этапе тестирования INSERT'а столкнулся с вышеописанной проблемой. Имеются ли на форуме "физиологи" postgresql, способные объяснить неразумному причину сабжа ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 07.04.2016, 10:10 |
|
||
|
ALTER TABLE из TRIGGER
|
|||
|---|---|---|---|
|
#18+
KraG, проверьте все триггера на инсерт на таблицу. судя по всему их там есть. и события возникают не одиночно, а парно и более. (инсерт порождает дилет или апдейт) И да, -- при [конкурентной работе и] любви к динамическому ддл вам надо в любом случае писать блок обработки исключений . если это непонятно -- физиологи тут бессильны. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 07.04.2016, 10:34 |
|
||
|
ALTER TABLE из TRIGGER
|
|||
|---|---|---|---|
|
#18+
KraG, Чтобы помочь по существу, предоставьте изолированный скрипт, который в пустой схеме сделает таблицу и триггиер. А потом покажет как это падает. Зачастую подготовка таких изолированных кейсов приводит к пониманию проблемы. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 07.04.2016, 10:52 |
|
||
|
ALTER TABLE из TRIGGER
|
|||
|---|---|---|---|
|
#18+
Прошу прощения за задержку (каждый раз, когда пишу эти слова, мне представляется девушка с положительным тестом...). Отдельно хочется отблагодарить vyegorov за идею "изолированного теста". Я подготовил скрипт для изолированного теста. Могу заранее сказать, что по результатам его выполнения проблема локализовалась и причина ее была выявлена (как мне кажется). Вот так, собственно, выглядит "изолированная" БД. Код: sql 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. 31. 32. 33. 34. 35. 36. 37. 38. 39. 40. 41. 42. 43. 44. 45. 46. 47. 48. 49. 50. 51. 52. 53. 54. 55. И по результатам INSERT'а получаем ту же самую ошибку. Однако, стоит удалить RULE emp_update с таблицы employees, то ошибка пропадает. Как мне думается, в рамках одной транзакции происходит: 1) INSERT в employees, по которому срабатывает триггер 2) Согласно правилу emp_update вместо INSERT'а почему то происходит UPDATE, по которому тоже срабатывает триггер 3) А в это время... вот тут я с механизмом выполнения транзакций толком не знаком. Я так представляю, что, где то в далекой далекой галактике кэше уже создано и готово воплотиться новое поле для таблицы permissions. А этот же триггер, сработавший на UPDATE уже видит в кэше это поле. Только при всем при этом мне не понятно, причем здесь правило. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 07.04.2016, 16:50 |
|
||
|
ALTER TABLE из TRIGGER
|
|||
|---|---|---|---|
|
#18+
KraG, Не мешайте RULE с триггерами. Никогда. Это еще никого до добра не довело. А лучше вообще забудьте RULE в принципе, у них крайне мало того что нельзя сделать триггерами и куча проблем (так как 99% разработчиков НЕ понимаю как они работают внутри). ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 07.04.2016, 17:00 |
|
||
|
ALTER TABLE из TRIGGER
|
|||
|---|---|---|---|
|
#18+
KraG, Забавно... похоже на баг. А какая версия Postgres'а? Судя по всему, триггер срабатывает и на INSERT, и на UPDATE — последний по правилу. Однако мне казалось, что триггера не должны стрелять до того, как правила выполнятся... (моё ИМХО, не уверен). В списках не советуют мешать правила и триггера: либо одно, либо другое. Вы точно так же можете "запретить" INSERT-ы триггером, сделав UPDATE в функции и вернув NULL из BEFORE триггера. Также можно попробовать сделать триггер AFTER, и он должен выстрелить только по UPDATE-у. Но мне думается, что отказаться от правила совсем будет лучше. И совсем хорошо будет завести статичную таблицу с предопределённым набором полей и не мучаться с такой динамикой совсем :) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 07.04.2016, 17:02 |
|
||
|
ALTER TABLE из TRIGGER
|
|||
|---|---|---|---|
|
#18+
vyegorovKraG, Забавно... похоже на баг. А какая версия Postgres'а? Судя по всему, триггер срабатывает и на INSERT, и на UPDATE — последний по правилу. Однако мне казалось, что триггера не должны стрелять до того, как правила выполнятся... (моё ИМХО, не уверен). Если я правильно понял, то "выполнение правила" есть модификация (если условие, при наличии оного, выполнится) SQL-инструкции до ее выполнения. В моем случае правило должно сработать по условию Код: sql 1. 2. 3. Однако, если это новое поле, то оно не выполняется. Теоретически. vyegorovВ списках не советуют мешать правила и триггера: либо одно, либо другое. Вы точно так же можете "запретить" INSERT-ы триггером, сделав UPDATE в функции и вернув NULL из BEFORE триггера. Также можно попробовать сделать триггер AFTER, и он должен выстрелить только по UPDATE-у. Но мне думается, что отказаться от правила совсем будет лучше. Согласен, что однообразие в какой то степени залог отсутствия неожиданного поведения. Но, в свою очередь скажу что я в какой то степени новоначальный и, что наверное естественно, не предполагал, что реализованный функционал может как то не дружить с другим функционалом. Хотя и это навряд ли, ибо, скорее всего, причина в том, что я просто не понимаю как, что и в какой последовательности работает. И дальше тут должна была быть тирада на пять страниц о том, что хочется впитать из книг или с потом фундаментальные знания и процессах, происходящих внутри postgresql во время выполнения того или иного кода. А книг таких нет... И времени тоже нет... Печаль, печаль. vyegorovИ совсем хорошо будет завести статичную таблицу с предопределённым набором полей и не мучаться с такой динамикой совсем :) У меня, как и у любого лентяя, есть патологическое желание сделать что то, что будет делать остальное за меня :) Но, предупреждая посты про то, что раз "такой лентяй, то и мучайся с динамикой, отлавливай эксепшены" и т.п. сразу сообщу, что внемлю вашим предостережениям. Буду использовать динамический DDL исключительно когда не договорюсь со своей ленью. Да и к тому же, какое это мучение? Это набивание шишек. Учебный, так сказать, процесс. $ psql --version psql (PostgreSQL) 9.5.2 Однако dpkg говорит, что и прежняя 9.3 все еще есть. Утверждать про баг пока рановато, ибо не видно, заменяет ли правило исходный код INSERT'а и, если да, то на какой код. Как бы это посмотреть? А то может я что то в правиле напортачил и дебажить надо мой код. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 08.04.2016, 08:58 |
|
||
|
ALTER TABLE из TRIGGER
|
|||
|---|---|---|---|
|
#18+
KraG, Вы добавляете имена пользователей в виде колонок к таблице `permissions`. Это означает, что вы не сможете написать 1 SQL запрос (параметризованный), который будет выбирать права для нужного пользователя. Вместо этого вы должны будете каждый раз формировать запрос динамически, т.к. идентификаторы (имена колонок в данном случае) не могут передаваться как параметры. Т.е. вы умышленно создаёте себе лишнюю работу и проблемы (это к вашему утрверждению про лень). Ещё раз: уберите правило совсем переделайте таблицу `permissions` к виду `(userid int4 PRIMARY KEY, can_login bool, is_admin bool)` (к примеру) также нужно повесить внешний ключ к таблице`employees` на поле `userid` в ON INSERT триггере добавляйте новую запись в таблицу, с нужным `userid` и умолчательными правами. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 08.04.2016, 10:31 |
|
||
|
ALTER TABLE из TRIGGER
|
|||
|---|---|---|---|
|
#18+
KraG Если я правильно понял, то "выполнение правила" есть модификация (если условие, при наличии оного, выполнится) SQL-инструкции до ее выполнения. В моем случае правило должно сработать по условию Код: sql 1. 2. 3. во первых вы неправильно поняли про правила. NEW [OLD] в правилах не записи, как в триггерах, а табличные наборы, типа как в мсскл inserted/deleted. а во вторых я только что вам соврал, поскольку они не табличные наборы, как таковые [однажды и навсегда], а правила для исчисления табличных наборов, как таковых. [в руле с несколькими последовательными стейтментами содержимое new / old может, сюрпрайс, меняться от стейтмента к стейтменту] ну и т.д.. т.е. руле с т.з. обычного скл--девелопера это такое запредельное говно, что назвать их изобредателя кроме как рукожопом не получается. хотя они, рулле энти, скорее всего могут местами улучшить производительность, там где вместо он роу цирканья можно поюзать нечто агрегирующее сразу весь набор (см аналогию с мсскл -- там в триггерах на стейтмент это обычное дело). типа крабле бумс. такие дела ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 08.04.2016, 10:34 |
|
||
|
ALTER TABLE из TRIGGER
|
|||
|---|---|---|---|
|
#18+
KraG Код: plsql 1. Посмотрел только на эту строчку. Судя по вашей логике, вы для каждого сотрудника добавляете столбец что-ли? Вам не приходило в голову, что эту простую логику можно реализовать добавляя строки, а не столбцы? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 08.04.2016, 11:02 |
|
||
|
ALTER TABLE из TRIGGER
|
|||
|---|---|---|---|
|
#18+
vyegorovKraG, Вы добавляете имена пользователей в виде колонок к таблице `permissions`. Это означает, что вы не сможете написать 1 SQL запрос (параметризованный), который будет выбирать права для нужного пользователя. Вместо этого вы должны будете каждый раз формировать запрос динамически, т.к. идентификаторы (имена колонок в данном случае) не могут передаваться как параметры. Т.е. вы умышленно создаёте себе лишнюю работу и проблемы (это к вашему утрверждению про лень). Ещё раз: уберите правило совсем переделайте таблицу `permissions` к виду `(userid int4 PRIMARY KEY, can_login bool, is_admin bool)` (к примеру) также нужно повесить внешний ключ к таблице`employees` на поле `userid` в ON INSERT триггере добавляйте новую запись в таблицу, с нужным `userid` и умолчательными правами. Категорически согласен с Вами, что так будет верно. Но при условии, если ролей всего две. Ну или *надцать. Я же хотел реализовать схему прав доступа на полноразмерной матрице, где каждый пользователь может получить права на доступ к другому пользователю. Или нескольким заранее определенным. И где количество или параметры пользователей меняются. Пока их около 200. Потому и появился соблазн динамически формировать таблицу (добавлять столбец и запись)... Про то, что придется формировать запрос динамически я не подумал. Каюсь и прошу у всех причастных прощения. Не тратил бы ваше время, если бы думал впрок. Хотя можно было бы названия полей генерировать вида наподобие a_1,a_2...a_n. А в запросе получать все поля и анализировать их на предмет NOT_NULL дальше.... Но, видимо, правильнее будет прийти к неким заранее определенным наборам (группам) и просто модифицировать таблицу employees добавлением одного поля. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 08.04.2016, 11:11 |
|
||
|
ALTER TABLE из TRIGGER
|
|||
|---|---|---|---|
|
#18+
Новичок ООП., тут скорее лучше какой-нибудь hstore использовать. если я правильно понял и там что-то вроде ACL храниться будет. либо нормализовать полностью, создав таблицу связей. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 08.04.2016, 11:16 |
|
||
|
ALTER TABLE из TRIGGER
|
|||
|---|---|---|---|
|
#18+
Новичок ООП., ээттаа неемпартивнаа тут интересно, насколько мы не понимаем, как работают руле. вот сделал набростки теста: Код: sql 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. 31. 32. 33. 34. 35. 36. 37. 38. 39. 40. 41. 42. 43. 44. 45. 46. 47. 48. 49. 50. 51. 52. 53. 54. 55. 56. 57. 58. 59. 60. --- после зависания лезть в spg_dtat_activity -- станет немного яснее. т.е. сначала модифицируется дерево исполнения запроса -- рулем. потом вставляется первая запись, в триггере, посколь в этот момент записис нет -- создаётся поле. потом, посколь дерево запроса отмодифачено, условию EXISTS для new.* начинает удовлетоврять первая запись (ещё не закомиченное) и руле срабатывает. срабатывает триггер на апдейт -- ... интересно, что в моем случае до апдейта не доходим -- висим на блокировке -- автономия ждёт коммита запустившей её транзакции. Т.е. руле. забавное поведение. а вот если логировать new.* а не (employees_1.* )::text -- то очереди не возникает. очень интересное поведение локов. не знал. т.е. ээто не баг - это настолько мы не понимаем механику руле. она супротив интуиций скл девелопера. она про интуиции разработчика движка . а они не совпадают. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 08.04.2016, 11:24 |
|
||
|
ALTER TABLE из TRIGGER
|
|||
|---|---|---|---|
|
#18+
KraG Я же хотел реализовать схему прав доступа на полноразмерной матрице, где каждый пользователь может получить права на доступ к другому пользователю. Или нескольким заранее определенным. И где количество или параметры пользователей меняются. Пока их около 200. Потому и появился соблазн динамически формировать таблицу (добавлять столбец и запись)... уберите эквивалентность роли (бизнес--роли) -- усеру. и можете возвращаться к вашей матрице. ролей не больше , чем захардкожено в бизнес приложении, т.е. конечное число, никакого динамического ддл усеров-- сколько хотите. для переменного по обоим измерениям представления матрицы есть связи "многие ко многим". (id1,id2,{properties}). немного медленнее плоского, но нет ограничений по спецификациям на кол--во столбцов. и нет динамического скл. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 08.04.2016, 11:34 |
|
||
|
ALTER TABLE из TRIGGER
|
|||
|---|---|---|---|
|
#18+
qwwqKraG Если я правильно понял, то "выполнение правила" есть модификация (если условие, при наличии оного, выполнится) SQL-инструкции до ее выполнения. В моем случае правило должно сработать по условию Код: sql 1. 2. 3. во первых вы неправильно поняли про правила. NEW [OLD] в правилах не записи, как в триггерах, а табличные наборы, типа как в мсскл inserted/deleted. а во вторых я только что вам соврал, поскольку они не табличные наборы, как таковые [однажды и навсегда], а правила для исчисления табличных наборов, как таковых. [в руле с несколькими последовательными стейтментами содержимое new / old может, сюрпрайс, меняться от стейтмента к стейтменту] ну и т.д.. т.е. руле с т.з. обычного скл--девелопера это такое запредельное говно, что назвать их изобредателя кроме как рукожопом не получается. хотя они, рулле энти, скорее всего могут местами улучшить производительность, там где вместо он роу цирканья можно поюзать нечто агрегирующее сразу весь набор (см аналогию с мсскл -- там в триггерах на стейтмент это обычное дело). типа крабле бумс. такие дела Я прошу прощения за свою "темноту", но если Вас не затруднит, что есть "табличные наборы"? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 08.04.2016, 11:42 |
|
||
|
ALTER TABLE из TRIGGER
|
|||
|---|---|---|---|
|
#18+
Новичок ООП.добавляя строки, а не столбцы?да и строки добавлять незачем, если не требуется различать false и null/отсутствие строки. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 08.04.2016, 11:58 |
|
||
|
ALTER TABLE из TRIGGER
|
|||
|---|---|---|---|
|
#18+
KraG Я прошу прощения за свою "темноту", но если Вас не затруднит, что есть "табличные наборы"?правильно -- я опять собирался вас обмануть, ага. но это не про табличные наборы а табличные наборы -- это наборы записей, типа возвратов SELECT -ов они могут существовать как материальные наборы (напр CTE в пж), так и как правила их исчисления (subselect) а врать я собрался ,потому как плохо помню, чем вот всё это кончилось: 1113147 давно это было да и в своём тутошнем тесте я транкейта видимо жду, а не rule -- добавил его , не подумав. (там эсклюзив на табличку транкейтом вешается). ну да не суть. порядок обработки он и так проясняет. важнее резюме -- никогда не пользуйте руле. даже если приспичит. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 10.04.2016, 11:36 |
|
||
|
|

start [/forum/topic.php?fid=53&fpage=93&tid=1997304]: |
0ms |
get settings: |
11ms |
get forum list: |
14ms |
check forum access: |
3ms |
check topic access: |
3ms |
track hit: |
46ms |
get topic data: |
7ms |
get forum data: |
2ms |
get page messages: |
89ms |
get tp. blocked users: |
1ms |
| others: | 250ms |
| total: | 426ms |

| 0 / 0 |
