简体   繁体   English

使用HugSQL通过ON CONFLICT DO UPDATE一次将多行插入PostgreSQL表中

[英]Using HugSQL to INSERT multiple rows at once into PostgreSQL table with ON CONFLICT DO UPDATE

I'm working with PostgreSQL and wanting to INSERT multiple rows at once with an ON CONFLICT DO UPDATE statement. 我正在使用PostgreSQL,并希望使用ON CONFLICT DO UPDATE语句一次INSERT多行。

I've got something like this: 我有这样的事情:

-- :name add-things! :! :n
INSERT INTO my_table (
  p,
  foo
)
VALUES :tuple*:values
ON CONFLICT (p) DO UPDATE
SET my_table.foo = foo

where p is the primary key. 其中p是主键。

I call this with: 我这样称呼:

(add-things! {:values [[1 1] [2 3]]})

But this returns: org.postgresql.util.PSQLException: ERROR: column reference "foo" is ambiguous . 但这返回: org.postgresql.util.PSQLException: ERROR: column reference "foo" is ambiguous

Using SET my_table.foo = :foo (with a keyword parameter) leads to clojure.lang.ExceptionInfo: Parameter Mismatch: :foo parameter data not found , because there are no keyword parameters when using the :tuple*:values syntax. 使用SET my_table.foo = :foo (带有关键字参数)会导致clojure.lang.ExceptionInfo: Parameter Mismatch: :foo parameter data not found ,因为在使用:tuple*:values语法时没有关键字参数。

Any idea how to accomplish this? 任何想法如何做到这一点? Maybe by using Clojure code in the HugSQL query? 也许通过在HugSQL查询中使用Clojure代码?

The problem here is the use of just foo inside the conflict resolution. 这里的问题是在冲突解决方案中仅使用foo There is a foo in the "insert data" and one on the actual table. “插入数据”中有一个foo,而实际表中有一个。 You need to address the "insert data" somehow to resolve that conflict. 您需要以某种方式解决“插入数据”以解决该冲突。 The solution as stated in the docs is: 文档中所述的解决方案是:

conflict_action specifies an alternative ON CONFLICT action. conflict_action指定了另一种ON CONFLICT动作。 It can be either DO NOTHING , or a DO UPDATE clause specifying the exact details of the UPDATE action to be performed in case of a conflict. 它可以是DO NOTHINGDO UPDATE子句,用于指定发生冲突时要执行的UPDATE操作的确切详细信息。 The SET and WHERE clauses in ON CONFLICT DO UPDATE have access to the existing row using the table's name (or an alias), and to rows proposed for insertion using the special excluded table . ON CONFLICT DO UPDATESETWHERE子句可以使用表名(或别名)访问现有行,并使用特殊excluded表访问建议插入的行

So 所以

...
SET foo = excluded.foo

solves the conflict. 解决冲突。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM