Reputation: 79
I have these 3 tables
recipe: recipe_id | name
ingredient: ingredient_id | name
recipes_ingredients: id | recipe_id | ingredient_id
The first id of every table is a SERIAL PRIMARY KEY
and the two names are character varying(50)
. I'm trying to insert in the third table recipe_id
and ingredient_id
using RETURNING
but it doesn't work. I already tried the three INSERT individually and they work perfectly, the problem seems to happen when i put altogether using the WITH or it cannot takes the returned ids.
Here's my SQL:
BEGIN; -- start transaction
WITH new_recipe AS (
INSERT INTO recipe (name) VALUES ('{}') RETURNING recipe_id
)
WITH new_ingredient AS (
INSERT INTO ingredient (name) VALUES ('{}') RETURNING ingredient_id
)
INSERT INTO recipes_ingredients (recipe_id, ingredient_id) VALUES (new_recipe.recipe_id, new_ingredient.ingredient_id)
COMMIT; -- end transaction
This is the error I get:
ERROR: syntax error at or near "WITH"
LINE 5: WITH new_ingredient AS (
^
SQL state: 42601
Character: 117
I already checked other similar question on stackoverflow and it seems to me that I used the exact same question. So I can't understand where the error is.
Upvotes: 1
Views: 36
Reputation:
If you want to write multiple common table expressions, the WITH
keyword is only needed once. The individual parts are separated by commas. But you can't reference the CTEs without using a SELECT, so the final INSERT needs to use a SELECT clause, not a VALUES clause:
WITH new_recipe AS (
INSERT INTO recipe (name) VALUES ('{}') RETURNING recipe_id
), new_ingredient AS (
INSERT INTO ingredient (name) VALUES ('{}') RETURNING ingredient_id
)
INSERT INTO recipes_ingredients (recipe_id, ingredient_id)
select new_recipe.recipe_id, new_ingredient.ingredient_id
from new_recipie
cross join new_ingredient;
;
Another option is to use the currval()
function together with pg_get_serial_sequence()
then you don't need the CTE at all:
INSERT INTO recipe (name) VALUES ('{}');
INSERT INTO ingredient (name) VALUES ('{}');
INSERT INTO recipes_ingredients (recipe_id, ingredient_id)
values (
currval(pg_get_serial_sequence('recipe', 'recipe_id')),
currval(pg_get_serial_sequence('ingredient', 'ingredient_id'))
);
Upvotes: 1