|
INSRT ... VALUES (DEFAULT)
|
|||
---|---|---|---|
#18+
Добрый день! Нужно при инсерте вставлять либо переданное значение, либо если оно NULL, до DEFAULT значение. Так как этот инсерт происходит в RULE на вьюху, просто опустить поле не получиться. Т.е. сейчас я делаю так: Код: plaintext 1. 2. 3. 4. 5.
Если поступать таким образом, то приходиться дублировать дефалтные значения и в описании таблицы, и во всех рулях где оно должно вставляться. А это усложняем дальнейшую поддержку и хочеться как нибудь от этого избавиться. Возможно ли? ... |
|||
:
Нравится:
Не нравится:
|
|||
01.10.2008, 17:45 |
|
INSRT ... VALUES (DEFAULT)
|
|||
---|---|---|---|
#18+
Прошло 12 лет. Проблема по-прежнему не решена... Или это никому не нужно ? ... |
|||
:
Нравится:
Не нравится:
|
|||
15.10.2020, 18:37 |
|
INSRT ... VALUES (DEFAULT)
|
|||
---|---|---|---|
#18+
Cyrax_02 Прошло 12 лет. Проблема по-прежнему не решена... Или это никому не нужно ? Никому не нужно... rule - deprecated де факто фича. Тем более что задача insert в view решается сейчас через instead of триггера которые нормально и предсказуемо (и понятно) работают в отличии от rule. -- Maxim Boguk лучшая поддержка PostgreSQL: dataegret.ru ... |
|||
:
Нравится:
Не нравится:
|
|||
15.10.2020, 18:40 |
|
INSRT ... VALUES (DEFAULT)
|
|||
---|---|---|---|
#18+
Maxim Boguk Никому не нужно... rule - deprecated де факто фича. Правила перезаписи запросов работают быстрее, чем триггеры , т.к. оптимизации подвергается результат развёртывания этих самых правил . Ещё и это: https://stackoverflow.com/questions/42520134/infinite-recursion-in-postgresql-rule#comment72194762_42520134 With high concurrency, a trigger based solution could fail... ... |
|||
:
Нравится:
Не нравится:
|
|||
15.10.2020, 19:05 |
|
INSRT ... VALUES (DEFAULT)
|
|||
---|---|---|---|
#18+
Maxim Boguk Тем более что задача insert в view решается сейчас через instead of триггера которые нормально и предсказуемо (и понятно) работают в отличии от rule Тогда интересно, как решается сабжевая задача на уровне триггеров (вставка переданного значения, а если не передано, то DEFAULT) ? ... |
|||
:
Нравится:
Не нравится:
|
|||
15.10.2020, 19:40 |
|
INSRT ... VALUES (DEFAULT)
|
|||
---|---|---|---|
#18+
Cyrax_02 Maxim Boguk Тем более что задача insert в view решается сейчас через instead of триггера которые нормально и предсказуемо (и понятно) работают в отличии от rule Тогда интересно, как решается сабжевая задача на уровне триггеров (вставка переданного значения, а если не передано, то DEFAULT) ? дайте полное описание задачи чтоли... -- Maxim Boguk лучшая поддержка PostgreSQL: dataegret.ru ... |
|||
:
Нравится:
Не нравится:
|
|||
15.10.2020, 20:54 |
|
INSRT ... VALUES (DEFAULT)
|
|||
---|---|---|---|
#18+
Maxim Bogukдайте полное описание задачи чтоли... Например, при вставке/обновлении записи в представлении для одного из полей нужно заменить значение NEW.fieldx на func(NEW.fieldx) . При этом все остальные поля сохраняются без изменений. Т.е. если некоторое поле не указано, должно сохраняться значение DEFAULT (при наличии), а не NULL. ... |
|||
:
Нравится:
Не нравится:
|
|||
15.10.2020, 21:39 |
|
INSRT ... VALUES (DEFAULT)
|
|||
---|---|---|---|
#18+
Cyrax_02 Maxim Bogukдайте полное описание задачи чтоли... Например, при вставке/обновлении записи в представлении для одного из полей нужно заменить значение NEW.fieldx на func(NEW.fieldx) . При этом все остальные поля сохраняются без изменений. Т.е. если некоторое поле не указано, должно сохраняться значение DEFAULT (при наличии), а не NULL. Да легко: Код: plsql 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16.
далее - ожидаемо имеем проблему: Код: plaintext 1. 2. 3. 4. 5.
а теперь фокус - прописываем default value в view явным образом: alter table v_test alter ctime set default now(); и все магически начинает работать Код: plaintext 1. 2. 3. 4. 5. 6.
-- Maxim Boguk лучшая поддержка PostgreSQL: dataegret.ru ... |
|||
:
Нравится:
Не нравится:
|
|||
15.10.2020, 22:19 |
|
INSRT ... VALUES (DEFAULT)
|
|||
---|---|---|---|
#18+
Maxim Bogukдалее - ожидаемо имеем проблему: insert into v_test (id) values (10); ERROR: null value in column "ctime" violates not-null constraint Неа. Так не пойдёт. Это ненормально. Внутри триггерной функции вставка выполняется не в представление, а в таблицу. Стало быть, на уровне этой вставки табличный DEFAULT должен использоваться по умолчанию. Возможны 2 реализации: 1 ) Если среди вставляемых полей некоторое поле отсутствует, внутри триггерной функции NEW.ctime должно иметь значение не NULL, а табличный DEFAULT для этого поля 2 ) NEW.ctime должно принимать некоторое специальное значение, отличное от NULL, соответствующее отсутствию значения во входных данных Судя по всему, в PostgreSQL не реализован ни один из этих вариантов. В итоге мы имеем нерешённую проблему, когда при вставке в таблицу отсутствующего значения NEW.ctime = NULL, при этом невозможно определить, вставляется значение NULL или значение отсутствует (данное поле не сохраняется). А это разные ситуации. В случае с правилом RULE INSTEAD OF такое поведение (бездействие) оправданно, поскольку правило применяется до выполнения запроса, а для каждой вставляемой записи значения будут разными. Но данное поведение ничем не оправданно в случае с триггерами, когда все сохраняемые значения на момент выполнения триггерной функции известны. Maxim Bogukа теперь фокус - прописываем default value в view явным образом: alter table v_test alter ctime set default now(); и все магически начинает работать В данном случае проблема не решается, а всего лишь обходится. Тем, что мы не допускаем ситуации, когда в поле ctime таблицы вставляется значение NULL: при вставке в представление отсутствующее поле ctime принимает значение DEFAULT = now() (ещё до вызова триггера) и в момент срабатывания триггера NEW.ctime равно now() , а не NULL. Тем самым, проблему мы обходим, но не решаем. ... |
|||
:
Нравится:
Не нравится:
|
|||
15.10.2020, 23:23 |
|
INSRT ... VALUES (DEFAULT)
|
|||
---|---|---|---|
#18+
Вариант с триггерами (на каждой вставляемой строке вызывается триггерная функция, и даже не SQL , а более тяжёлая pgplSQL ): Код: plsql 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12.
Вариант с правилами (никакие функции не вызываются вообще): Код: plsql 1. 2.
Риторический вопрос : какой вариант проще и быстрее ? ... |
|||
:
Нравится:
Не нравится:
|
|||
15.10.2020, 23:38 |
|
INSRT ... VALUES (DEFAULT)
|
|||
---|---|---|---|
#18+
Cyrax_02 Вариант с триггерами (на каждой вставляемой строке вызывается триггерная функция, и даже не SQL , а более тяжёлая pgplSQL ): Код: plsql 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12.
Вариант с правилами (никакие функции не вызываются вообще): Код: plsql 1. 2.
Риторический вопрос : какой вариант проще и быстрее ? На абсолютно любой мыслимой задаче - глубоко пофигу а реализация с триггером намного понятнее и проще в обслуживании и модификации. Если же у вас действительно важна разница в скорости этих реализаций (100.000insert/s в одну таблицу) то вам надо 1)вообще через сишную хранимку вставлять и не извращаться с записью в view вообще или 2)подумать что это скорее всего не задача для реляционной базы... -- Maxim Boguk лучшая поддержка PostgreSQL: dataegret.ru ... |
|||
:
Нравится:
Не нравится:
|
|||
15.10.2020, 23:59 |
|
INSRT ... VALUES (DEFAULT)
|
|||
---|---|---|---|
#18+
Cyrax_02 Возможны 2 реализации: 1 ) Если среди вставляемых полей некоторое поле отсутствует, внутри триггерной функции NEW.ctime должно иметь значение не NULL, а табличный DEFAULT для этого поля 2 ) NEW.ctime должно принимать некоторое специальное значение, отличное от NULL, соответствующее отсутствию значения во входных данных Судя по всему, в PostgreSQL не реализован ни один из этих вариантов. В итоге мы имеем нерешённую проблему, когда при вставке в таблицу отсутствующего значения NEW.ctime = NULL, при этом невозможно определить, вставляется значение NULL или значение отсутствует (данное поле не сохраняется). А это разные ситуации. Оба варианта не возможны архитектурно в принципе без критического обьема переделки кода... Если вам оно сильно чешется - patch welcome Но 90% что его завернут потому что визгу много а шерсти мало (в смысле патч очень большой инвазивный и меняющий уже существующее поведение но особо никому не нужный). Первый еще и не дает возможность в before insert триггере понять что от insert поле таки не пришло (и отличить от вставки DEFAULT значения явной) и что то с этим сделать - то есть получить зеркальную проблему от той что вы пытаетесь решить (и не факт что она приятнее). А второй - полный ад в реализации с переписыванием кучи кода. -- Maxim Boguk лучшая поддержка PostgreSQL: dataegret.ru ... |
|||
:
Нравится:
Не нравится:
|
|||
16.10.2020, 00:07 |
|
|
start [/forum/search_topic.php?author=maxus-paxus&author_mode=last_posts&do_search=1]: |
0ms |
get settings: |
10ms |
get forum list: |
16ms |
get settings: |
9ms |
get forum list: |
11ms |
check forum access: |
4ms |
check topic access: |
4ms |
track hit: |
153ms |
get topic data: |
10ms |
get forum data: |
2ms |
get page messages: |
48ms |
get tp. blocked users: |
1ms |
others: | 441ms |
total: | 709ms |
0 / 0 |