powered by simpleCommunicator - 2.0.52     © 2025 Programmizd 02
Форумы / PostgreSQL [игнор отключен] [закрыт для гостей] / Не работает (WITH + UPSERT + UPDATE)
6 сообщений из 6, страница 1 из 1
Не работает (WITH + UPSERT + UPDATE)
    #40033537
Cyrax_02
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Код: sql
1.
2.
3.
4.
WITH upsert AS (
   INSERT INTO test (id, name) VALUES (2,'old name'::text)
   ON CONFLICT (id) DO UPDATE SET id = EXCLUDED.id, name = EXCLUDED.name WHERE test.id = EXCLUDED.id RETURNING id
) UPDATE test SET name = 'new name' FROM upsert WHERE test.id = upsert.id;


Здесь вложенный в WITH запрос работает корректно (обновляет существующую запись с id = 2 и возвращает эту запись главному запросу).
Главный запрос у полученной записи с id = 2 должен изменить name . Но главный запрос ничего не меняет.

Если условие (test.id = upsert.id) заменить на (test.id <> upsert.id), то главный запрос меняет name у всех записей, кроме id = 2 .
Т.е. условие (test.id = upsert.id) срабатывет, но запись ( name ) не меняется. Бред какой-то...

P.S . Очевидно, что если два запроса выполнить отдельно, проблем не будет. Но в случае с WITH происходит какая-то петрушка...
...
Рейтинг: 0 / 0
Не работает (WITH + UPSERT + UPDATE)
    #40033550
Фотография Maxim Boguk
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Cyrax_02,

Как обычно внимательно читаем документацию в части https://www.postgresql.org/docs/13/queries-with.html#QUERIES-WITH-MODIFYING
Особенно предпоследний абзац звучащий как:

документацияTrying to update the same row twice in a single statement is not supported. Only one of the modifications takes place, but it is not easy (and sometimes not possible) to reliably predict which one. This also applies to deleting a row that was already updated in the same statement: only the update is performed. Therefore you should generally avoid trying to modify a single row twice in a single statement. In particular avoid writing WITH sub-statements that could affect the same rows changed by the main statement or a sibling sub-statement. The effects of such a statement will not be predictable.

почему так - написано выше по тексту.

В общем результат unspecified и так делать не надо.



--
Maxim Boguk
лучшая поддержка PostgreSQL: dataegret.ru
...
Рейтинг: 0 / 0
Не работает (WITH + UPSERT + UPDATE)
    #40033614
Cyrax_02
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Код: sql
1.
2.
3.
4.
5.
6.
UPDATE test SET name = 'new name' FROM (
   INSERT INTO test (id, name) VALUES (2,'old name'::text)
   ON CONFLICT (id) DO UPDATE SET id = EXCLUDED.id, name = EXCLUDED.name WHERE test.id = EXCLUDED.id RETURNING id
) upsert WHERE test.id = upsert.id;

SQL Error [42601]: ОШИБКА: ошибка синтаксиса (примерное положение: "INTO")


Тогда получается, что одним запросом никаким способом невозможно выполнить последовательные UPSERT + UPDATE на одной и той же строке ?

Maxim BogukОсобенно предпоследний абзац звучащий как:Этот абзац я читал. Только вот под оператором я понимал одну несоставную команду (в данном случае UPSERT или UPDATE).
Как оказалось, речь идёт в т.ч. и о составных командах.
...
Рейтинг: 0 / 0
Не работает (WITH + UPSERT + UPDATE)
    #40033667
Фотография Maxim Boguk
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Cyrax_02
Код: sql
1.
2.
3.
4.
5.
6.
UPDATE test SET name = 'new name' FROM (
   INSERT INTO test (id, name) VALUES (2,'old name'::text)
   ON CONFLICT (id) DO UPDATE SET id = EXCLUDED.id, name = EXCLUDED.name WHERE test.id = EXCLUDED.id RETURNING id
) upsert WHERE test.id = upsert.id;

SQL Error [42601]: ОШИБКА: ошибка синтаксиса (примерное положение: "INTO")


Тогда получается, что одним запросом никаким способом невозможно выполнить последовательные UPSERT + UPDATE на одной и той же строке ?

Maxim BogukОсобенно предпоследний абзац звучащий как:
Этот абзац я читал. Только вот под оператором я понимал одну несоставную команду (в данном случае UPSERT или UPDATE).
Как оказалось, речь идёт в т.ч. и о составных командах.

Одним запросом - нельзя без использования хранимых процедур.

WITH это одна монолитная команда а не составная... составная команда это когда несколько sql запросов в одной строке отправляются через ; .
Никогда не стоит смешивать в голове WITH c несколькими блоками и несколько sql комманд через ; - это очень разные вещи и работают по разному.

PS: не могу понять в каком реальном use case вам такая странная задача понадобилась. Обычно подобные вещи через BEFORE триггер решаются.

--
Maxim Boguk
лучшая поддержка PostgreSQL: dataegret.ru
...
Рейтинг: 0 / 0
Не работает (WITH + UPSERT + UPDATE)
    #40033685
Cyrax_02
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Maxim BogukWITH это одна монолитная команда а не составная... Под " составной командой " в предыдущем посте я имел ввиду многоблочную команду с WITH , а не " запрос; запрос ; ...".

Maxim BogukPS: не могу понять в каком реальном use case вам такая странная задача понадобилась. Обычно подобные вещи через BEFORE триггер решаются. Подобные - это какие ? Выполнение BEFORE-триггером операции INSERT или UPDATE в зависимости от значений полей (для этого есть UPSERT) ?
Сабжевый пример с точки зрения логики абсолютно бессмыслен (упрощённая форма реального запроса, воспроизводящая проблему).
...
Рейтинг: 0 / 0
Не работает (WITH + UPSERT + UPDATE)
    #40033691
Фотография Maxim Boguk
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Cyrax_02

Maxim BogukPS: не могу понять в каком реальном use case вам такая странная задача понадобилась. Обычно подобные вещи через BEFORE триггер решаются.
Подобные - это какие ? Выполнение BEFORE-триггером операции INSERT или UPDATE в зависимости от значений полей (для этого есть UPSERT) ?
Сабжевый пример с точки зрения логики абсолютно бессмыслен (упрощённая форма реального запроса, воспроизводящая проблему).

такие это когда надо сложную логику реализовать перед тем как менять что то в таблице
в вашем случае это "выполнить последовательные UPSERT + UPDATE надо одной строкой в пределах 1 запроса"


--
Maxim Boguk
лучшая поддержка PostgreSQL: dataegret.ru
...
Рейтинг: 0 / 0
6 сообщений из 6, страница 1 из 1
Форумы / PostgreSQL [игнор отключен] [закрыт для гостей] / Не работает (WITH + UPSERT + UPDATE)
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]