Insert if not exists, else return id in postgresql
我在PostgreSQL中有一个简单的表,它有三列:
- ID系列主键
- 密钥VARCHAR
- 价值VARCHAR
我已经在这里看到这个问题了:在postgresql中插入,在重复更新时?但我想知道,如果ID存在,如何获取它,而不是更新它。如果标准实践总是"插入"或"如果存在则更新",为什么会这样?执行选择(限制1)的成本是否大于执行更新?
我有以下代码
1 2 3 4 5 6 7 | INSERT INTO tag ("key","value") SELECT 'key1', 'value1' WHERE NOT EXISTS ( SELECT id,"key","value" FROM tag WHERE KEY = 'key1' AND VALUE = 'value1' ); |
如果存在,它就不会插入,但我想获取ID。是否有一个"返回ID"子句或类似的东西可以在里面点击?
是的,有EDOCX1[0]
1 2 3 4 5 6 7 8 | 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" |
如果行已经存在,则返回该行
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | 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"对中的一个或两个都可以为空。
1 2 3 4 5 6 7 8 | 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小提琴演示
您可以存储返回到变量的值,形式为…返回field1,field2,…变为var1,var2,…
如果不使用返回的结果集在plpgsql中调用查询,则返回的查询通常会返回错误"query has no destination for result data"。