对不起,后续问题(来自INSERT into table if doesn't exists and return id in both cases)
但是我找不到任何解决方案。
我有一个反馈表,其列是其他表的外键。对于前。 scopeid是作用域表中id列的前导键,类似地,userid是用户表中id列的外键,依此类推。
因此,我正在尝试在表中插入以下数据: 范围:首页, 用户名:abc 状态:固定 应用:demoapp
因此,要插入上述数据,我试图编写子查询以获取每个值的ID并使用该ID。另外,如果该值不存在,则插入并使用新ID将其插入反馈表中。
所以基本上,我试图插入多个表(如果不存在)并使用这些ID插入到最终表(即反馈表)中。
希望现在情况更加清楚
这是我的反馈表:
id scopeid comment rating userid statusid appid
3 1 test 5 2 1 2
所有id列都是其他表的外键,因此在下面的查询中,我尝试按名称获取id,如果不存在,则添加它们。
这是我的最后一个查询:
INSERT INTO feedbacks (scopeid, comment, rating, userid, statusid, appid)
VALUES
(
-- GET SCOPE ID
(
WITH rows_exists AS (
SELECT id FROM scope
WHERE appid=2 AND NAME = 'application'),
row_new AS (INSERT INTO scope (appid, NAME) SELECT 2, 'application' WHERE NOT EXISTS (SELECT id FROM scope WHERE appid=2 AND name='application') returning id)
SELECT id FROM rows_exists UNION ALL SELECT id FROM row_new
),
-- Comment
'GOD IS HERE TO COMMENT',
-- rating
5,
-- userid
(
WITH rows_exists AS (
SELECT id FROM users
WHERE username='abc'),
row_new AS (INSERT INTO users (username) SELECT 'abc' WHERE NOT EXISTS (SELECT id FROM users WHERE username='abc') returning id)
SELECT id FROM rows_exists UNION ALL SELECT id FROM row_new
),
-- statusid
(SELECT id FROM status WHERE NAME='received'),
-- appid
(
WITH rows_exists AS (
SELECT id FROM apps
WHERE name='google'),
row_new AS (INSERT INTO apps (name) SELECT 'google' WHERE NOT EXISTS (SELECT id FROM apps WHERE NAME='google') returning id)
SELECT id FROM rows_exists UNION ALL SELECT id FROM row_new
)
)
但我收到以下错误消息:
with包含数据修改语句的子句必须位于顶层
通过这种方式或其他方法,我什至有可能实现这一目标。
答案 0 :(得分:1)
以下代码插入不存在的ID,然后插入结果ID:
with s as (
select id
from scope
where appid = 2 AND NAME = 'application'
),
si as (
insert into scope (appid, name)
select v.appid, v.name
from (values (2, 'application')) v(appid, name)
where not exists (select 1 from scope s where s.appid = v.appid and s.name = v.name)
returning id
),
. . . similar logic for other tables
insert into feedback (scopeid, comment, . . . )
select (select id from s union all select id from is) as scopeid,
'test' as comment,
. . .;
您应该确保在每个表中对于要查找的值都有唯一的约束。否则,您可能会遇到竞争状况,并最终在多线程环境中多次插入同一行。