如果不存在,则插入,否则返回postgresql中的id
我在PostgreSQL中有一个简单的表,它有三列:如果不存在,则插入,否则返回postgresql中的id,postgresql,Postgresql,我在PostgreSQL中有一个简单的表,它有三列: id串行主键 钥匙瓦查尔 varchar值 我已经在这里看到了这个问题:但是我想知道如果id存在,如何获取它,而不是更新。如果标准惯例总是“插入”或“更新(如果存在)”,为什么?执行SELECT(限制1)的成本是否大于执行更新的成本 我有以下代码 INSERT INTO tag ("key", "value") SELECT 'key1', 'value1' WHERE NOT EXISTS ( S
- id串行主键
- 钥匙瓦查尔
- varchar值
INSERT INTO tag
("key", "value")
SELECT 'key1', 'value1'
WHERE
NOT EXISTS (
SELECT id,"key","value" FROM tag WHERE key = 'key1' AND value = 'value1'
);
如果存在,它不会插入,但我想获取id。是否有“RETURNING id”子句或类似的东西,我可以在其中点击?是的,有
正在返回
INSERT INTO tag ("key", "value")
SELECT 'key1', 'value1'
WHERE NOT EXISTS (
SELECT id, "key", "value"
FROM node_tag
WHERE key = 'key1' AND value = 'value1'
)
returning id, "key", "value"
如果行已存在,则返回该行
with s as (
select id, "key", "value"
from tag
where key = 'key1' and value = 'value1'
), i as (
insert into tag ("key", "value")
select 'key1', 'value1'
where not exists (select 1 from s)
returning id, "key", "value"
)
select id, "key", "value"
from i
union all
select id, "key", "value"
from s
如果该行不存在,它将返回插入的行,否则返回现有行
顺便说一句,如果对“key”/“value”使其唯一,则它是主键,不需要id列。除非“键”/“值”对中的一个或两个可以为空
with vals as (
select 'key5' as key, 'value2' as value
)
insert into Test1 (key, value)
select v.key, v.value
from vals as v
where not exists (select * from Test1 as t where t.key = v.key and t.value = v.value)
returning id
并且您可以将返回给变量的值以。。。返回字段1,字段2,。。。变成var1,var2
RETURNING通常会返回一个查询,如果您在plpgsql中调用它而不使用返回的结果集,则该查询将返回错误“query has no destination for result data”。经过仔细检查,我意识到该解决方案实际上并没有达到我的期望,因为除非INSERT有效,否则它不会返回任何内容(即,如果键值对以前不在表中)。如果该行已经在表中,它只返回空白(不是预期的ID)。我之前没有返回该行的原因是我在测试它时无意中输入了一个错误(因此键值对不在表中,因此它返回了该行的ID).BTW:可能是
UNION ALL
,IMHO.@wildplasser注意到,无论使用ALL
,始终只返回一行。从语义上说,你是对的。但我严重怀疑乐观主义者是否会意识到这一点。(当然,这是徒劳的)对于一行来说,它是可以忽略的。但它可能会影响计划的生成/选择(只有当涉及多行时才可以检测到),删除重复项的成本并不高,但它可能会迫使两个子计划以特定顺序(不需要)返回它们的此处问题和答案的可能重复项比此处的投票结果好得多,并且此处的访问次数要高得多,因此如果必须关闭某个问题,则是另一个问题,而不是此问题。仅供参考,Postgres 9.5提供了一个功能。请参阅。此处的可能重复项