Вставка в несколько таблиц с CTE У меня не работает - PullRequest
0 голосов
/ 18 июня 2020

Я видел здесь несколько ответов для некоторых распространенных случаев использования CTE для вставки в несколько таблиц, при попытке выполнить те же шаги я получаю сообщение об ошибке:

Отсутствует запись From-clause для таблица "first_insert" позиция 824.

Мое выражение CTE выглядит следующим образом:

with first_insert as (
    insert into listing (title, slug, price, min_quantity, serves, currency_name, currency_symbol, img_url, description,
                         location, g_map_address, vendor_id)
        values ('hello', 'hello-1234', 1, 12, 10, 'eur', '€','url.jpg',
                'description', point(24.5498, 16.26), 'gmap', 1)
        RETURNING id
),
     second_insert as (
         insert into category (name, suggested_name, link, rel_link, listing_id)
             select 'name', 'name', 'link', 'rel_link', id
             from first_insert
     ),
     third_insert as (
         insert into allergen (name, suggested_name, link, rel_link, listing_id)
             select 'name', 'name', 'link', 'rel_link', id
             from first_insert
     )
insert into image(listing_id, img_url) select first_insert.id, 'imgUrl';

1 - Как я могу заставить это работать, поскольку вставки не требуются, поэтому не уверен, с чего начать.

2 - Это лучший способ с точки зрения производительности для выполнения этих типов вставок?

3 - Классифицируется ли это как безопасные вставки, если они есть одна из вставок не работает, когда уже выполненные вставки откатываются?

4 - Есть ли в целом способ сделать такую ​​вставку лучше с точки зрения производительности и безопасности?

1 Ответ

1 голос
/ 19 июня 2020

1 - Как я могу заставить это работать, поскольку вставки не требуются, поэтому не уверен, с чего даже начать с этого

Он жалуется на "последний" запрос, вы в нем нет предложения FROM. Должно получиться так:

...
insert into image(listing_id, img_url) select id, 'imgUrl' from first_insert;

2 - Это лучший способ с точки зрения производительности для выполнения этих типов вставок?

Производительность должна быть аналогична выполнению BEGIN + 4 вставки как отдельные запросы + COMMIT. Это может быть немного быстрее, потому что вы сохраняете сетевые обходы между приложением и базой данных, но я не думаю, что это будет иметь значение для обычного приложения. Я бы использовал любой способ, который кажется вам более читаемым / удобным для вас.

3 - Классифицируется ли это как безопасная вставка, так что если какая-либо из вставок выйдет из строя, а уже выполненные вставки будут отменены?

Да, запросы в Postgres автоматически выполняются в рамках своей собственной транзакции (если вы еще не начали свою транзакцию). Это означает, что все или ни один из его эффектов записывается на диск, но никогда не разделяется.

4 - Есть ли лучший общий способ сделать такую ​​вставку с точки зрения производительности и безопасности?

Я не думаю, что есть лучший способ повышения производительности. В целях безопасности это так же безопасно, как выполнение 4 вставок отдельно в транзакции.

Для удобства обслуживания / чтения, я бы сказал, что лучше делать 4 вставки отдельно в транзакции. Он менее эзотерический c и более гибкий. Что, если в будущем вы захотите вставить в allergen только при соблюдении определенного условия? Если вы выполняете запросы по отдельности, очень легко добавить if, но если вы выполняете их все в одном большом запросе, это становится более сложным.

...