我有一张桌子:
CREATE TABLE mytable (id SERIAL, name VARCHAR(10) PRIMARY KEY)
现在我想将名称添加到该表中,但前提是它们已经不存在于表中,并且在这两种情况下都返回id
. 我怎样才能用 PostgreSQL 做到这一点?
我已经看到了一些脚本,但是没有单一的 SQL 语句可以做到这一点吗?
例如,我可以插入并返回id
:
INSERT INTO mytable (name) VALUES ('Jonas') RETURNING id
它第一次工作并返回id
。但是如果表中已经存在它会失败,但是即使插入失败Jonas
,我也想返回。id
这可能与PostgreSQL有关吗?
Upsert 语句曾经计划用于 9.1,但已被推迟到 9.2,因此在此之前,您唯一的选择是在插入之前测试该值是否已经存在。
或者,如果您只想拥有一个唯一标识符,则可以简单地使用序列 + nextval。
如果你想创建一个函数来做到这一点,这应该让你开始:
如果您使用的是 9.1,则有一种使用可写 CTE 的解决方法
http://xzilla.net/blog/2011/Mar/Upserting-via-Writeable-CTE.html
我认为在单个 SQL 语句中很难做到这一点。也许您应该编写一个函数来执行此操作。这是我个人的看法。因为即使 sql 出现“错误:重复键值”,您也想返回 id。
我喜欢简单地捕捉这里提出的 unique_violation 异常:
忽略重复插入的最佳方法?
这个解决方案的美妙之处在于它不受竞争条件的影响。您必须将代码添加到异常处理程序以查找 id。