【问题标题】:Upsert in PostgreSQLPostgreSQL 中的更新插入
【发布时间】:2022-01-26 14:20:14
【问题描述】:

我正在尝试使用另一个表的字段在一个表中执行 upsert,我尝试使用 On Conflict “下面的代码”,但它总是给我这个错误:“Errore SQL [42601]: ERROR : “from”处或附近的语法错误 位置:926" 但如果我要删除“从编排编排”,它会给我这个异常:“Errore SQL [42P01]:错误:缺少表“编排”的 FROM 子句条目 位置:334" 有人可以帮我吗?

insert into ro_banche (id_banca,code_abi, code_fisc, desc_banca, desc_banca_rid, data_attivaz, data_cessaz, code_abi_nuovo, code_abi_trasf, code_abi_cor, code_abi_nocor, code_abi_giro, flag_tipo_ades, code_tipo_istituto, data_modifica, utente_modifica)
select * from orchestrate 
ON CONFLICT (code_abi) DO 
update set code_fisc = orchestrate.code_fisc, desc_banca = orchestrate.desc_banca, desc_banca_rid = orchestrate.desc_banca_rid, data_attivaz = orchestrate.data_attivaz, data_cessaz = orchestrate.data_cessaz, code_abi_nuovo = orchestrate.code_abi_nuovo, code_abi_trasf = orchestrate.code_abi_trasf, code_abi_cor = orchestrate.code_abi_cor, code_abi_nocor = orchestrate.code_abi_nocor, code_abi_giro = orchestrate.code_abi_giro, flag_tipo_ades = orchestrate.flag_tipo_ades, code_tipo_istituto = orchestrate.code_tipo_istituto, data_modifica = orchestrate.data_modifica, utente_modifica = orchestrate.utente_modifica
from orchestrate orchestrate
where (ro.code_abi = orchestrate.code_abi);

【问题讨论】:

  • 为什么在 FROM 子句中写两次orchestrate?只有一次应该没问题。
  • 您不能使用“select *”,您需要以与您定义的目标的列列表匹配的顺序明确列出列。否则,您的流程如何知道源中的哪些列需要插入目标中的哪些列?

标签: sql postgresql


【解决方案1】:

语法中不需要额外的FROM

由于该更新处于记录级别,对于那些因重复而发生冲突的人。

你想从excluded更新

INSERT INTO ro_banche
(id_banca, code_abi, code_fisc, desc_banca, desc_banca_rid, data_attivaz, data_cessaz, code_abi_nuovo, code_abi_trasf, code_abi_cor, code_abi_nocor, code_abi_giro, flag_tipo_ades, code_tipo_istituto, data_modifica, utente_modifica)
SELECT 
 id_banca, code_abi, code_fisc, desc_banca, desc_banca_rid, data_attivaz, data_cessaz, code_abi_nuovo, code_abi_trasf, code_abi_cor, code_abi_nocor, code_abi_giro, flag_tipo_ades, code_tipo_istituto, data_modifica, utente_modifica
FROM orchestrate 
ON CONFLICT (code_abi) DO 
UPDATE SET 
  code_fisc = excluded.code_fisc
, desc_banca = excluded.desc_banca
, desc_banca_rid = excluded.desc_banca_rid
, data_attivaz = excluded.data_attivaz
, data_cessaz = excluded.data_cessaz
, code_abi_nuovo = excluded.code_abi_nuovo
, code_abi_trasf = excluded.code_abi_trasf
, code_abi_cor = excluded.code_abi_cor
, code_abi_nocor = excluded.code_abi_nocor
, code_abi_giro = excluded.code_abi_giro
, flag_tipo_ades = excluded.flag_tipo_ades
, code_tipo_istituto = excluded.code_tipo_istituto
, data_modifica = excluded.data_modifica
, utente_modifica = excluded.utente_modifica;

dbfiddle here

上的简化测试
insert into test1 (num, col)
select * 
from test2 
where col < 9
on conflict (num) do
update set col = excluded.col

dbfiddle here

上的简化测试 2(无主键)
do $$
begin 
  update test1 t1 
  set col = t2.col
  from test2 t2 
  where t2.num = t1.num;
  
  insert into test1 (num, col)
  select num, col
  from test2 t2
  where not exists (
    select 1
    from test1 t1
    where t1.num = t2.num
  );
end $$;

【讨论】:

  • 非常感谢,最后一个问题,如果我没有唯一的字段,但我想 ckìheck 是否相同的值(整行)与另一行相同,我应该怎么做写冲突原因?
  • 嗯。 CONFLICT 语法确实期望匹配字段是主键或具有唯一索引。我已经在解决方案中添加了一个示例,以应对情况并非如此。基于this SO post
  • 但是请注意,如果您使用更新和插入方法,最好在表中唯一的字段组合上执行此操作。或者如果可能的话,添加一个唯一索引。
猜你喜欢
  • 2014-10-16
  • 1970-01-01
  • 1970-01-01
  • 2012-03-19
  • 2014-01-15
  • 2021-01-06
  • 2013-01-24
  • 2014-01-15
  • 1970-01-01
相关资源
最近更新 更多