Этот баннер — требование Роскомнадзора для исполнения 152 ФЗ.
«На сайте осуществляется обработка файлов cookie, необходимых для работы сайта, а также для анализа использования сайта и улучшения предоставляемых сервисов с использованием метрической программы Яндекс.Метрика. Продолжая использовать сайт, вы даёте согласие с использованием данных технологий».
Политика конфиденциальности
|
|
|
??? <<Defaults may also be created for views>>
|
|||
|---|---|---|---|
|
#18+
авторSET/DROP DEFAULT These forms set or remove the default value for a column. The default values only apply to subsequent INSERT commands; they do not cause rows already in the table to change. Defaults may also be created for views, in which case they are inserted into INSERT statements on the view before the view's ON INSERT rule is applied. Кто пояснит, КАК Defaults may also be created for views? (Я бусь тут второй день. Че то не в понятках). Проблема примерно такая: две таблы связь 1:1 (Left join). Кей (id) - счетчик в главной. Написал давненько вью на INSERT - DO INSTED ... VALUES (new.id ...) - в обе таблицы. Теперь надо втыкать новые данные, не высчитывая заранее main.id (там суррогатный ключ - счетчик). Если вставлять все кроме id во вью - ругань на NULL в id. (т.е. получается, что new.id - NULL и попытка вставить, ес-но, не работает). Если писать INSERT INTO view_my (id,....) SELECT nextval('my_id_seq'::text) AS id,...FROM .... (где nextval('my_id_seq'::text) - DEFAULT для main.id - транзакция какое-то время крутится, потом приходит ругань на отcутствие ключа связи между main И slave (в оба ключа пытаюсь воткнуть, как говорилось, new.id). Причем, если смотреть на приращение счетчика в транзакции, то получается примерно удвоенное число вставляемых записей (которые так и не вставляются) - т.е. такое впечатление, что в new.id ВМЕСТО значения nextval('my_id_seq'::text) оба раза поступает ВЫРАЖЕНИЕ и оба раза вычисляется. Конечно это мои домыслы, но сильно на то похоже. Инсерт же конкретных значений id проходит нормально (если их еще нет в таблицах). Вот теперь ищу, как обеспечить передачу DEFAULT во VIEW (вернее в RULE _INSERT)? ! нужно же явно отличать случай явной вставки NULL в поле с DEFAULT от попытки вставить данные во все поля VIEW кроме дефаултных - КАК? Если даже писать INSERT .... SELECT .... CASE WHEN new.id IS NULL THEN DEFAULT ELSE new.id END, - это, кажется не рулит проблему - в обоих случаях будет NULL). Postgres 7.3.4. И хто писал уже полностью функциональные вью со счетчиками DEFAULT-ами, да вставкой их (вычислимых дефалтов, т.е.) в нескоко та блиц, вспоможите убогому да криворукому ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 16.11.2004, 13:55 |
|
||
|
??? <<Defaults may also be created for views>>
|
|||
|---|---|---|---|
|
#18+
Методом тыка нашел: Код: plaintext 1. (опять долбанные перлы со скрытыми SQL свойствами, как это было в 7.2. с констрайнтами), НО, после этого вставка во вью величин без id ПЕРЕСТАЕТ ругаться на NULL и начинает ругаться на отсутствие величин для связи (в точности как при вставке nextval()) Уроды, млин. Пусть и бесплатные. Итого тест: Код: 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. Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. Код: 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. 31. 32. 33. 34. 35. 36. 37. 38. 39. 40. 41. 42. 43. 44. блин, ну очевидная ошибка в логике интерпретатора при передаче в NEW не величин, а выражений. Может это для чего-то сгодится, но изврат. т.е. получается, что ничего не получается в чистом SQL. Вызвать здзпыйд (plpgsql)? Дык а там сколько будут вызываться new.xxx ? Только в момент передачи, или при каждом вызове? Хотя, т.к. мне еще надо ветвить процедуру при отсутствии данных для присоединенной таблицы (не вставлять пустышек), то от этого, похоже не уйти (выполнить что-то из разряда: CASE WHEN ... INSERT .... ELSE DO NOTHING; END; похоже не получицца) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 16.11.2004, 16:05 |
|
||
|
??? <<Defaults may also be created for views>>
|
|||
|---|---|---|---|
|
#18+
Похоже действительно default для view подставляется буквально в каждое вхождение в правиле. Но я чего-то не понял, что мешает написать: Код: plaintext 1. 2. 3. 4. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 17.11.2004, 03:43 |
|
||
|
??? <<Defaults may also be created for views>>
|
|||
|---|---|---|---|
|
#18+
Мешает то, что это же вью должно работать при непосредственной передаче m_id в запрос на вставку во вью. (должно быть полнофункциональной реализацией обновляемого вью, независимо от способа передачи в него данных. ведь могут быть случаи, например заливки данных снаружи, для чего я использую обычно отрицательную область m_id (вернее в отрицательную область растет автонумерация, а заливка идет в положительную), когда в этих заливаемых данных есть некая ссылочная целостность, которую хотелось бы сохранить). В вашем случае связанная запись попытается сослаться не на вновь создаваемую главную, с переданным мной "руками" значением m_id, а на ранее добавленную. Что недопустимо. Проблема не в том, что дефаулт вычисляется несколько раз. Логическая ошибка в том, что NEW передается в rule как выражение , а не как значение (т.е. как нечто вычисляемое всякий раз внутри одной и той же транзакции - что неверно по самой сути NEW - набора ЗНАЧЕНИЙ новой записи). Дефаулт тут выступает только как способ определить NEW при отсутствии явно задаваемых значений. Та же проблема и при вставке с явной передачей выражения в качестве NEW.m_id (т.е. без использования DEFAULT). Но процедура должна работать и с явно передаваемыми величинами. И совсем не обязательно я передам в нее счетчик. Могу и любое выражение/значение. И если оно будет вычисляться внутри RULE много раз, вычисляя все новые значения - получится полный бред. (Вернее полный бред уже есть - в реализации передачи NEW в RULE). "Разруха - она в головах" Вот если я делаю: Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. Поэтому пока вижу только такой способ: ... Код: plaintext 1. (или SELECT my_sql_procedure(new);) где внутри my_xxx_procedure new пользуется только однажды - в присвоении значений внутренним переменным буду смотрет в эту сторону. ДА, еще прорезалась идея - темповая таблица (вернее, постоянная, с типом vmain_d но для переброски записей) Код: plaintext 1. 2. 3. 4. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 17.11.2004, 11:04 |
|
||
|
??? <<Defaults may also be created for views>>
|
|||
|---|---|---|---|
|
#18+
Мдя. Получилось как то так: Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. - ошибка - дубликаты m_id insertov. как я понял, DELETE работает на стейтмент, а INSERT - на каждую запись... (если закомментировать все кроме первого DELETE FROM vmain_temp; INSERT INTO vmain_temp (m_id,m_name,a_name ) VALUES (new.m_id,new.m_name,new.a_name); то после INSERT INTO vmain_d (m_name, a_name) SELECT m_name, a_name FROM vmain_d; увидим в vmain_temp несколько записей. (хотя если бы руле работал целиком на каждую запись - осталась бы только одна. ____________ Попробовал спастись (что тоже идеалогически неверно, даже если бы заработало): Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. Кудыть крестьянину поддаться? ___________ Так и есть: Руле оперирует с записями таблиц только до начала транзакции (при DELETE видимо тоже) Ибо: Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. Код: plaintext Т.е. опять возвращаемся к функции, как единственно возможному решению. Убивать ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 17.11.2004, 12:38 |
|
||
|
??? <<Defaults may also be created for views>>
|
|||
|---|---|---|---|
|
#18+
Все воопше еще более непонятно: Сношу все ключи в таблицах, Делаю: Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. в main добавляется 3+9 записей (так и ожидалось - 3х3 - из предыдущего опыта) а во вторую 3+36!!!. А этто еще откудова? - "Ниччего не понимаю" тут уж даже и предположить что-либо сложно. Что там происходит??? Ряд такой (вставляем n (1,2,3,4 ...) записей по одной, потом - все еще раз): 1+1 - 1 + 2 2+4 - 2+12 3+9 - 3+36 4+16 - 4 + 80 5 + 25 - 5 + 150 т.е. n + n*n - записей в первую и n + n*n*(n+1) записей во вторую с какой это радости? А если будет 3 таблицы? _____________ ...ттттак, кажется начинаю понимать.... new - это набор записей (не для юзера, для которого он рекорд, а внутри реализации). Если для него определение (SELECT m_name, a_name FROM vmain_d;) , то при входе во вторую инструкцию SQL (SELECT ...) имеет n записей (и для каждой выполняется INSERT всех записей из vmain_temp), а при входе в 3-ю new ПЕРЕВЫЧИСЛЯЕТСЯ и имеет уже n + n*n = (n+1)*n записей... и для каждой из них INSERT n записей из vmain_temp выполняется. Т.е. Rule работает для каждой инструкции столько раз, сколько в его *NEW* записей, затем переходит к следующей инструкции. Если за это время число записей в выражении для *NEW* изменится - количество попыток вставки тоже увеличится. Уроды. (надеюсь хоть сессии то разделены?) Лапотники, мать их... __________ Кстати, данный глюконат не есть следствия моих ухищрений с темповой таблицей: если не пользоваться темповой таблицей, то имеем ту же хрень: Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. n+n - в первую n + 2*n - во вторую (к третьему предложению SQL число записей в NEW, т.е. в SELECT ... FROM main становится равным 2*n) Кстати забавно: при вставке/удалении внутри RULE новые записи не учитываются, а при определении числа записей в NEW - вовсю принимают участие. Полный писец. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 17.11.2004, 14:11 |
|
||
|
??? <<Defaults may also be created for views>>
|
|||
|---|---|---|---|
|
#18+
мдя... Очередной облом Решил посмотреть, что будет если: Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. Если же вернуть вторичный ключ, то: Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. Даже не могу представить, что такое происходит - ведь добавление записей в одну из таблиц означает, что они добавлялись в обе... Тааак. Пробую: Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. (и эти люди еще пишут сихмы, индексы и прочие крючечки Удолбы, ля) Нет, я понимаю, что скорее всего чего-то попросту не понимаю, и есть оно, есть то удивительно простое и удобное средство, поюзав которое, все искомое можно реализовать вполне прозрачным способом, не углубляясь в особенности внутренней реализации правил в постгрессе и обхождение фич, которые мне, непосвященному, кажутся о'high-енными багами... И что даже некие хуру просто ленятся поправить мои дилетантские трепыхания в требуемую сторону, не смотря на мои попытки задеть их самолюбие, поливая на все лады их любимый инструмент (ну, т.е. не самый любимый Не в смысле старика Фрейда ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 18.11.2004, 11:58 |
|
||
|
??? <<Defaults may also be created for views>>
|
|||
|---|---|---|---|
|
#18+
Итак. Проблема с CASCADE прояснилась (вернее запуталась еще сильнее): Когда я выполнял предыдущий тест я отсылал все запросом из окна pgAdmin-а пачкой (т.е. сразу все что написано). Судя по всему отсюда ноги и растут. Судя по всему такая посылка эквивалентна BEGIN;.... COMMIT; Что впрочем неочевидно. Если посылать запросы на вставку "по одному" - все выглядит пристойно. Странно. (Ниччего не понимаю) __________ ЗЫ (Что интересно, разделение вставки на 2 инструкции не сняло проблемы с удалением вставленных было в main_add записей. Делал так: Код: 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. 31. 32. ____________ ЗЫ2: Откатил RULE на CREATE OR REPLACE RULE "vmain_sql_INSERT" AS ON INSERT TO vmain_sql DO INSTEAD ( SELECT vmain_sql_insert(new.m_id, new.m_name, new.a_name ); ); и попытался оформить транзакцию: Код: plaintext 1. 2. 3. 4. 5. 6. 7. ____________ Резюме: - поведение руле несколько неоднозначное. Зависит от того, как я запускаю запросы - "пакетом", или же по одному. Что настораживает даже больше, чем неприятная любовь к повторному вычислению *NEW*. Кто-нибудь может пояснить возможный источник последнего трабла ("с затиранием" записей в main_ad при "пакетном" запуске запросов на вставку из PgAdmin)? ________ ЗЗЫ: Кажется что-то тут вот с этим: В ODBC клиенте или PgAdmin пишем так: Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. - затирает за собой вставку в main_add , если же снять комментарии с BEGIN; и COMMIT; - затирать перестает (проверил и из ODBC клиента - Access - все так же). Что кажется мне непонятным. Что-то лезет не в ту транзакцию? Что-то не так закрывается? "Что это, Сигизмунд?" ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 18.11.2004, 17:05 |
|
||
|
??? <<Defaults may also be created for views>>
|
|||
|---|---|---|---|
|
#18+
Жаль, что никого не интересуют данные проблемы: Итак: 0. NEW для руле передается не как значение, а как выражение. Причем для самого набора записей это тоже имеет место. Отсюда: 1. Писать Rule на INSERT или UPDATE или DELETE в несколько таблиц в виде @простой SQL конструкции@ из набора последовательных SQL инструкций - в корне неверно для постгрес (при нынешней реализации исполнения правил в 7.3.4). Т.к. для каждой инструкции набор NEW определяются заново. И если например в базовом запросе для вставки участвуют таблицы самого вида (точнее таблицы, в которые руле пишет изменения), то сам набор записей будет меняться от одной инструкции руле к другой. (Это похоже на ситуацию, если бы SQL инструкция INSERT пересчитывала набор записей для вставки после каждой вставленной записи, а не после стейтмента. Возможно ничего и в этом плохого не будет (можно придумать, как жить и в этом случае), но в случае постгресс имеем "двойной стандарт" - в руле идет дискретный пересчет набора записей между инструкциями, но для каждой инструкции набор записей фиксирован). Вернее написать RULE таким образом можно, но придется все время помнить о его весьма ограниченной применимости. Т.е. аналогия такого представления с таблицей никогда не будет полна. 2. Можно писать руле на INSERT как функцию, но существуют какие-то проблемы с использовантем таких руле в транзакциях*. ___ * - что тут происходит -я не могу понять. 1. Пока допетрил, что постгресс, похоже, умудряется обходиться без вложенных транзакций. 2. Почему-то мне не удается использовать INSERT во вью внутри объявленной мною транзакции. (т.е. если я руками запускаю по одной команде: BEGIN; INSERT ...; и т.п.- то транзакция завершается сама собой после первого же инсерта, и никакие ROLLBACK; или ошибки в наборе последующих команд ее уже не откатят. Если же я просылаю _пачку_ начатую с BEGIN; и завершающуюся не важно COMMIT; ом или ROLLBACK; -ом, из любого клиента (PgAdmin, Access) то записи не вставляются. Но отнести это на ошибки в транзакции мне сложно - лог PgAdmin пишет только WARNING, но не пишет никаких ERROR; Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. а поскольку он таки доходит до COMMIT; не выдавая сообщения об ошибке в транзакции или ее зависании - можно думать, что транзакция таки закочилась раньше (когда - вопрос сложный) ибо если написать: Код: plaintext 1. 2. 3. 4. 5. 6. 7. Полюбому, INSERT В таблицу И INSERT во вью (по крайней мере в моем случае - с использованием ф-ий) не равноправны по отношению к явно объявленной транзакции. INSERT во вью закрывает транзакцию. Но в случае просылки SQL инструкций из клиента "пакетом", похоже есть еще и "откат" пакета. Я было предположил, что любой "пакет" откатится, если в нем больше одного COMMIT;-а, но нет, это как-то завязано именно на руле (или ф-ю в нем). Т.к. если послать последовательно несколько явных ("рукописных") commit-off (в отличие от предполагаемо мною неявного коммита "просылаемого" из руле, видимо еще и отложенного до конца "пакета") именно в случае обычной вставки в таблицу - записи вставятся. Если же прослать хотя бы один коммит из "пакета" с явно объявленной транзакцией, в которой наряду с "обычными" вставками в "нормальные" таблицы делается хотя бы один INSERT во вью - откатится вся транзакция (если коммита явно не посылать - транзакция завершится успешно, как писалось выше). ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 19.11.2004, 12:53 |
|
||
|
??? <<Defaults may also be created for views>>
|
|||
|---|---|---|---|
|
#18+
> (при нынешней реализации исполнения правил в 7.3.4). А может стоит обновиться до версии 8.0 Beta 4? Posted via ActualForum NNTP Server 1.1 ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 19.11.2004, 17:47 |
|
||
|
??? <<Defaults may also be created for views>>
|
|||
|---|---|---|---|
|
#18+
Stas TristanА может стоит обновиться до версии 8.0 Beta 4? проверил на 8.0.0beta1 --- те же яйца (nextval вызывается 2 раза). я бы предложил автору этого опуса написать баг-репорт --- если разработчиков не пинать, то они это и не исправят никогда. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 19.11.2004, 18:14 |
|
||
|
??? <<Defaults may also be created for views>>
|
|||
|---|---|---|---|
|
#18+
Sad Spirit проверил на 8.0.0beta1 --- те же яйца (nextval вызывается 2 раза). Спасибо. Уже собирался сам. Но все ленюсь поставить 8-ку домой. ("В выходные надо отдыхать", типа ). Правда остается вопрос с закрытием транзакции руле-м в 7.3 vs 8.0 (или руле-м с функцией - не дотестировал до полной ясности). Т.ч. ставить таки придется. (Руле с ф-ей снимает траблы с повторным пересчетом NEW, что меня бы устроило, но лезут непонятки с транзакциями. Если в 8.0. это снято - то и ладушки. А если я сам в чё не въехал - зараз и просеку ). Sad Spirit я бы предложил автору этого опуса написать баг-репорт --- если разработчиков не пинать, то они это и не исправят никогда. Блин, как я не люблю эти напряги с формулировкой мыселюков на инородском наречии... Но подумаю. Хотя версия постгреса, на котором все тут у нас будет продолжать вертеться меньше всего зависит от меня). "говорил ломая руки красный бай Ебало Муд" (ВВС) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 22.11.2004, 10:44 |
|
||
|
??? <<Defaults may also be created for views>>
|
|||
|---|---|---|---|
|
#18+
Sad Spirit проверил на 8.0.0beta1 --- те же яйца (nextval вызывается 2 раза). я бы предложил автору этого опуса написать баг-репорт --- если разработчиков не пинать, то они это и не исправят никогда. Писать не стал, но нашел любопытное: http://archives.postgresql.org/pgsql-bugs/2004-11/msg00141.php т.е, как я понял, вещь давно известная (там же есть рекурсивный баг, возникающий, как мне показалось, из той же модели многократного пересчета NEW (вникать до конца не стал), но только в случае множественного RULE с WHERE (интересно, а если в рулевом WHERE стоит new.xxx, то оно тоже множественно пересчитывается?). И видимо разработчиков вполне устраивает это состояние дел, равно как и принятая модель исполнения руле. Если я чё не так понял - звиняюсь. Т.е. выход все тот же - в однократном вызове в руле ф-ии вместо набора инструкций. И единственная проблема - включение каких либо руле во внешнюю транзакцию. Они, похоже, таки не будут включаться так же, как апдейты на обычные таблицы. (Просматриваю баг лист выборкой по {RULE COMMIT ROLLBACK и т.п.} пока до конца не въехал) ЗЫ : (там же проходит тема по поводу выбора триггеров вместо руле. Не понял. Разве на вью можно повесить триггер (ON INSERT/UPDATE)???) This comes up often and the response is usually something like, "Rules are macros, which is why referring to NEW.id causes another evaluation of nextval(). If you don't want that to happen then use a trigger." ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 22.11.2004, 19:13 |
|
||
|
??? <<Defaults may also be created for views>>
|
|||
|---|---|---|---|
|
#18+
Тоже сталкнулся с проблемой нескольких update'ов в rule on update. Вылечилось вызовом функции, которая уже делала необходимые апдэйты. В функцию передается new. Т.е. поля перечеслять не надо. CREATE OR REPLACE FUNCTION update_fzdaten(n v_fzdaten) RETURNS void AS $BODY$ begin UPDATE fzbrief SET id = n.id, ... WHERE fzbrief.id = n.id; UPDATE fzdaten SET fahrzeugid = n.id,... WHERE fzdaten.fahrzeugid = n.id; return; end $BODY$ LANGUAGE 'plpgsql' VOLATILE; CREATE OR REPLACE RULE v_fzdaten_update AS ON UPDATE TO v_fzdaten DO INSTEAD SELECT update_fzdaten(new) AS update_fzdaten; ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 02.09.2005, 17:01 |
|
||
|
|

start [/forum/topic.php?fid=53&msg=32786439&tid=2007038]: |
0ms |
get settings: |
5ms |
get forum list: |
12ms |
check forum access: |
2ms |
check topic access: |
2ms |
track hit: |
128ms |
get topic data: |
7ms |
get forum data: |
2ms |
get page messages: |
31ms |
get tp. blocked users: |
1ms |
| others: | 242ms |
| total: | 432ms |

| 0 / 0 |
