Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/typo3/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如果不存在,则插入,否则返回postgresql中的id_Postgresql - Fatal编程技术网

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

如果不存在,则插入,否则返回postgresql中的id,postgresql,Postgresql,我在PostgreSQL中有一个简单的表,它有三列: id串行主键 钥匙瓦查尔 varchar值 我已经在这里看到了这个问题:但是我想知道如果id存在,如何获取它,而不是更新。如果标准惯例总是“插入”或“更新(如果存在)”,为什么?执行SELECT(限制1)的成本是否大于执行更新的成本 我有以下代码 INSERT INTO tag ("key", "value") SELECT 'key1', 'value1' WHERE NOT EXISTS ( S

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

  • id串行主键
  • 钥匙瓦查尔
  • varchar值
我已经在这里看到了这个问题:但是我想知道如果id存在,如何获取它,而不是更新。如果标准惯例总是“插入”或“更新(如果存在)”,为什么?执行SELECT(限制1)的成本是否大于执行更新的成本

我有以下代码

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提供了一个功能。请参阅。此处的可能重复项