如果不存在则插入,否则在postgresql中返回id

时间:2013-08-12 16:57:24

标签: postgresql

我在PostgreSQL中有一个简单的表,它有三列:

  • id serial primary key
  • key varchar
  • value varchar

我已经在SO上发现了这个问题:Insert, on duplicate update in PostgreSQL?但是我想知道如果它存在,如何获取id,而不是更新。如果标准做法是始终“插入”或“如果存在则更新”,为什么会这样? SELECT(LIMIT 1)的成本是否大于UPDATE?

我有以下代码

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”条款或类似的内容我可以在那里点击?

3 个答案:

答案 0 :(得分:76)

是的,有returning

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列。除非“key”/“value”对中的一个或两个都可以为null。

答案 1 :(得分:6)

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

sql fiddle demo

答案 2 :(得分:-1)

并且您可以将返回值的值存储为... RETURNING field1,field2,... INTO var1,var2,...

RETURNING通常会返回一个返回错误的查询错误'查询没有结果数据的目标'如果你在plpgsql中调用它而不使用它返回的结果集。