我正在使用WITH运行两个INSERT语句(表A和表B)。第一个INSERT语句具有ON CONFLICT子句,如果A.name中有重复项,则不要。第二条语句依赖于成功插入到表A中,因此它试图在表B中输入空值。NOTHHING对第一条语句不执行任何操作,但是第二条语句继续执行,如何停止它?
WITH first_insert AS (INSERT INTO
groups(group_cuid,group_name,created_by,date_created)
VALUES ($1,$2,(SELECT user_id
FROM users
WHERE users.cognito_id='${created_by}'),
(SELECT now()::timestamp))
ON CONFLICT ON CONSTRAINT group_name_unique DO NOTHING
RETURNING id,created_by
)
INSERT INTO groups_users_rel(group_id,user_id,is_admin,date_joined)
VALUES (
(SELECT id FROM first_insert),
(SELECT created_by FROM first_insert),
true,
(SELECT now()::timestamp)
)
RETURNING *
如果在GROUPS表中发生插入,我希望在GROUPS_USERS_REL表中进行插入。如果有冲突,我希望整个查询结束。而是在第一次插入时根据CONFLICT将空值插入GROUPS_USERS_REL。
如果有更简便的方法来进行上述任何操作,请随时发表评论。
答案 0 :(得分:1)
INSERT INTO ... VALUES (...)
将始终尝试使用您提供的值列表准确插入一条记录。当查询SELECT id FROM first_insert
不返回记录时,子查询(SELECT id FROM first_insert)
的计算结果为NULL
,因此这就是表中的内容。
如果要插入可变数量的行(即零或一),则需要一个INSERT INTO ... SELECT ...
语句,其中SELECT
决定要添加的行(如果有)。
在您的情况下,它看起来像这样:
WITH first_insert AS (
...
)
INSERT INTO groups_users_rel(group_id,user_id,is_admin,date_joined)
SELECT
id,
created_by,
true,
now()::timestamp
FROM first_insert
RETURNING *
答案 1 :(得分:0)
Nick Barnes给出的答案解决了您遇到的问题。但是,我注意到了另一个清理您的代码的机会:
代替使用VALUES
子句SELECT user_id FROM users
,而是提供要在查询参数中插入的常量。制作完整的查询文本:
WITH first_insert AS (
INSERT INTO groups (group_cuid, group_name, created_by, date_created)
SELECT
$1
, $2
, user_id
, now()
FROM users
WHERE users.cognito_id = '${created_by}'
ON CONFLICT ON CONSTRAINT group_name_unique DO NOTHING
RETURNING id, created_by, true, now()
)
INSERT INTO groups_users_rel (group_id, user_id, is_admin, date_joined)
SELECT *
FROM first_insert
RETURNING *;