[英]Is it possible to capture the ID of a created row in postgres to use in the same query?
TL; DR,我想知道是否可以在 postgres 中創建一個資源,然后創建另一個引用它的資源,所有這些都在同一個語句中。 我想這樣做是為了減少往返時間並簡化我的后端邏輯。
我目前有兩個資源,foo 和 bar。 Bar 是引用它的 foo 的子資源:
CREATE TABLE foos (
id serial PRIMARY KEY,
name VARCHAR ( 50 ) UNIQUE NOT NULL
);
CREATE TABLE bars (
id serial PRIMARY KEY,
name VARCHAR ( 50 ) NOT NULL,
description VARCHAR ( 50 ),
foo_id int NOT NULL,
FOREIGN KEY (foo_id)
REFERENCES foos (id),
UNIQUE (foo_id, name)
);
我目前有以下 sql 語句在端點v1/foos/{foo_name}/bars/{bar_name}
上插入 foo 和 bar:
WITH upsert_foo AS
(
INSERT INTO "foos"
("name")
VALUES
($1)
ON CONFLICT ("name") DO NOTHING
),
upsert_bar AS
(
INSERT INTO "bars"
("name", "description", "foo_id" )
VALUES
($2, $3,
(SELECT "id" FROM "foos" WHERE "name" = $1) )
ON CONFLICT ("name", "foo_id") DO
UPDATE SET
"description" = EXCLUDED."description",
RETURNING *
)
SELECT upsert_bar.*;
當用戶 upsert 一個 bar 時,如果它不存在,則應創建一個名稱來自 URI 的 foo,如果它不存在則應創建該 bar。 否則,應該更新欄。
但是,此語句僅適用於更新情況,即 foo 資源已經存在。 新創建的 foo 似乎沒有出現在(SELECT "id" FROM "foos" WHERE "name" = $1)
中。
有沒有辦法可以捕獲已創建(或已存在)的 foo 的 ID 並在創建欄 object 時使用它?
我唯一能想到的就是將其分解為單獨的操作:
INSERT INTO
"foos" ("name")
VALUES
($1)
ON CONFLICT ("name") DO UPDATE
SET name = foos.name
RETURNING id;
上面有一個丟棄的UPDATE
用於捕獲id
值。 將此值保存到變量中以用作下面的$4
。
然后:
INSERT INTO
"bars" ("name", "description", "foo_id" )
VALUES
($2, $3, $4)
ON CONFLICT ("name", "foo_id") DO UPDATE
SET "description" = EXCLUDED."description"
RETURNING *
我設法在一個語句中完成了這項工作,但這有點復雜:
WITH insert_foo AS
(
INSERT INTO "foos"
("name")
VALUES
($1)
ON CONFLICT ("name") DO NOTHING RETURNING *
),
upsert_foo AS
(
SELECT * FROM insert_foo
UNION
SELECT * FROM foos WHERE "name"=$1
),
upsert_bar AS
(
INSERT INTO "bars"
("name", "description", "foo_id" )
VALUES
($2, $3, (SELECT "id" FROM upsert_foo WHERE name=$1) )
ON CONFLICT ("name", "foo_id") DO
UPDATE SET
"description" = EXCLUDED."description"
RETURNING *
)
SELECT * FROM upsert_bar;
基本上,插入的結果應該與常規的 select 查詢聯合,其中只有一個包含一行,具體取決於 foo 是否已經存在。 然后我可以 select 來自此聯合查詢結果的 id。
我想向 Adrian Klaver 大聲喊叫,因為他指出了我正確的方向以及這個答案: https://stackoverflow.com/a/62205017/4600258
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.