Postgresql

INSERT .. ON CONFLICT DO UPDATE SET 錯誤

  • August 7, 2020

當我使用以下查詢時:

cur.execute("""INSERT INTO TABLE
(SELECT ID_tmp,First_seen_tmp,Last_seen_tmp,Duration_tmp
FROM tmp_table)
ON CONFLICT (ID)
DO
UPDATE SET Last_seen=tmp_table.Last_seen_tmp,Duration=tmp_table.Last_seen_tmp-First_seen;""")

我不斷收到此錯誤:

psycopg2.errors.UndefinedTable: missing FROM-clause entry for table "tmp_table"
LINE X: UPDATE SET Last_seen=tmp_table.Last_seen_tmp,Duration=tmp...

即使我嘗試使用特殊表 EXCLUDED 引用可能的插入值,程式碼如下:

cur.execute("""INSERT INTO TABLE
(SELECT ID_tmp,First_seen_tmp,Last_seen_tmp,Duration_tmp
FROM tmp_table)
ON CONFLICT (ID)
DO
UPDATE SET Last_seen=EXCLUDED.Last_seen_tmp,Duration=EXCLUDED.Last_seen_tmp-First_seen;""")

我得到另一個錯誤:

psycopg2.errors.UndefinedColumn: column excluded.last_seen_tmp does not exist
LINE X: UPDATE SET Last_seen=EXCLUDED.Last_seen_tmp,Duration=EXCLUDE...

是否不可能使用帶有 INSERT .. ON CONFLICT CLAUSE 的 tmp 表中的值更新原始表的值?

記錄需要引用目標表中的excluded列,而不是源表(例如,VALUES 子句無論如何都不會有任何列名)。

始終在INSERT語句中指定目標列也是一種很好的編碼習慣。

INSERT INTO the_table (id, first_seen, last_seen, duration)
SELECT ID_tmp, First_seen_tmp, Last_seen_tmp, Duration_tmp
FROM tmp_table
ON CONFLICT (ID)
DO UPDATE 
  SET last_seen = EXCLUDED.last_seen,
      duration = EXCLUDED.last_seen - the_table.first_seen;

引用自:https://dba.stackexchange.com/questions/273383