无法获取从 INSERT 返回的 ID 并插入另一个 table

Cannot manage to take ids returned from INSERT and insert into another table

我有这 3 tables

食谱:recipe_id | name

成分:ingredient_id | name

recipes_ingredients: id | recipe_id | ingredient_id

每个table的第一个id是一个SERIAL PRIMARY KEY,两个名字是character varying(50)。我正在尝试使用 RETURNING 在第三个 table recipe_idingredient_id 中插入,但它不起作用。我已经分别尝试了三个 INSERT,它们工作得很好,当我完全使用 WITH 或者它不能接受返回的 ID 时,问题似乎发生了。

这是我的 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

这是我得到的错误:

ERROR:  syntax error at or near "WITH"
LINE 5: WITH new_ingredient AS (
        ^
SQL state: 42601
Character: 117

我已经在 Whosebug 上检查了其他类似的问题,在我看来我使用了完全相同的问题。所以我无法理解错误在哪里。

如果要写多个common table expressionsWITH关键字只需要一次。各个部分以逗号分隔。但是如果不使用 SELECT 就无法引用 CTE,因此最终的 INSERT 需要使用 SELECT 子句,而不是 VALUES 子句:

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;
;

另一种选择是将 currval() 函数与 pg_get_serial_sequence() 一起使用,那么您根本不需要 CTE:

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'))
       );