【问题标题】:Issues using INSERT INTO ON CONFLICT using WITH queries使用 WITH 查询使用 INSERT INTO ON CONFLICT 的问题
【发布时间】:2018-10-25 11:09:27
【问题描述】:

我正在将查询从 Oracle 数据库更改为 PostgreSQL,在此查询中我收到此错误:

 ERROR: syntax error at or near "ON"

查询是:

WITH d as (
      SELECT ? AS summary, ? AS eventTime), ai as (select * from alarm)
ON (ai.fault_id=? AND ai.external_key=?)
INSERT INTO alarm AS ai(
     alarm_id,
     fault_id,
     external_key)
VALUES (nextval('seq_alrm_instnc_alrm_instnc_id'),?,?)
ON CONFLICT DO UPDATE SET
        (${buildUpdateAttributes(attributes)}
        ai.summary = d.summary,
        ai.system_last_update_time = default,
        ai.event_sequence_number =
          CASE
            WHEN (d.event_number > ai.event_number) THEN d.event_number
            ELSE ai.event_number
          END)

我使用JDBC连接数据库,这里是调用代码

try (PreparedStatement ps = super.prepareStatement_(sql_query)) {
    PreparedStatementHelper psh = new PreparedStatementHelper(ps);
    psh.add(attribute1);
    ...
    ps.execute()

我尝试了不同的方法并仔细查看了 Postgres 文档,但找不到问题所在,也没有找到针对这种特定情况的任何答案

【问题讨论】:

  • 我不明白 CTE (WITH d as ...) 应该在那里做什么。为什么要为 INSERT 的 values 子句中的摘要列提供值?而eventTime 在后续语句中根本没有使用。而select * from alarm 在该声明中毫无意义。并且别名 d 不包含名为 event_number 的列,因此引用 d.event_number 也是无效的。而且你不能把整个 SET 部分放在括号之间
  • 尝试删除 ON 部分并将条件放在 WHERE 中。见reference

标签: java postgresql jdbc postgresql-10


【解决方案1】:

我真的不明白你想在那里做什么,你以错误的方式混合了这么多语法元素,真的很难理解。

这两个 CTE (WITH ...) 似乎完全不相关。如果您只想提供一些值并在违反 UNIQUE 键时进行更新,则基本语法是:

insert into the_table (col_1, col_2, col_3, col_4)
values (1,2,3,4)
on conflict (col_1,col_2) do update 
  set col_3 = excluded.col_3,
      col_4 = excluded.col_4;

特殊关键字excluded 用于引用导致违反唯一约束的行的VALUES 子句中提供的列值。

您的 CTE 提供了一个参数eventTime,以后再也不会使用它了。假设应该是event_number,那么也许你正在寻找这样的东西:

INSERT INTO alarm 
  -- specify all columns for which you provide a value 
  (alarm_id, fault_id, external_key,summary, event_sequence_number, event_number)
VALUES 
  -- provide a value for each column
  (nextval('seq_alrm_instnc_alrm_instnc_id'), ?, ?, ?, ?, ? )
  -- define the columns of the unique constraint you want to "catch"
ON CONFLICT (fault_id, external_key) 
DO UPDATE SET
   -- "excluded.summary" refers to the corresponding value from the VALUES clause
   summary = excluded.summary, 
   system_last_update_time = default,
   -- excluded.event_number refers to the corresponding value from the VALUES clause
   event_sequence_number = CASE
                             WHEN excluded.event_number > alarm.event_number THEN excluded.event_number
                             ELSE alarm.event_number
                           END

【讨论】:

  • 嘿伙计,谢谢。我真的不知道 PostGres 甚至 Oracle 的基本元素,所以我试图使用我在 Oracle Query 中的内容来尝试迁移。这也不是真正的查询,因为该查询至少有 20 个以上的字段,所以我试图简化。我会试试你说的
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-01-11
  • 1970-01-01
  • 2017-04-02
相关资源
最近更新 更多