PostgreSQL 9.5 UPSERT规则

时间:2017-06-20 08:13:20

标签: postgresql upsert

我在可更新的视图系统中有一个INSERT规则,为此我想实现一个UPSERT,例如:

CREATE OR REPLACE RULE _insert AS
ON INSERT TO vue_pays_gex.bals
DO INSTEAD (
INSERT INTO geo_pays_gex.voie(name, code, district) VALUES (new.name, new.code, new.district)
ON CONFLICT DO NOTHING;

但是我可以有这三列的许多不同组合,我认为我不能设置包含它们的CONSTRAINT(尽管我可能在SQL逻辑中缺少理解点),因此使ON无效CONFLIT没有任何部分。

理想的解决方案似乎是使用EXCEPT,但它只能在INSERT INTO SELECT语句中使用。有没有办法使用INSERT INTO SELECT语句引用新插入的行?像FROM new.bals(在我的情况下)?

如果不是,我可以想象一个不存在的条件,但出现了与以前相同的问题。

我猜这是一个相当常见的SQL需求,但找不到如何解决它。有什么想法吗?

编辑:

根据要求,这是表格定义:

CREATE TABLE geo_pays_gex.voie
(
  id_voie serial NOT NULL,
  name character varying(50),
  code character varying(15),
  district character varying(50),
  CONSTRAINT prk_constraint_voie PRIMARY KEY (id_voie),
  CONSTRAINT voie_unique_key UNIQUE (name, code, district)
);

2 个答案:

答案 0 :(得分:1)

您如何定义唯一性?如果它是name + code + district的组合,则只需在表UNIQUE(name, code, district)上添加约束geo_pays_gex.voie。 3,一起必须是unique ...但你可以有几次相同的名字,代码,或区。

http://rextester.com/EWR73154

上查看

编辑 ***

由于您可以拥有Null并希望将它们视为唯一值,因此可以使用替换空值的唯一索引替换约束创建

CREATE UNIQUE INDEX
voie_uniq ON voie
(COALESCE(name,''), code, COALESCE(district,''));

答案 1 :(得分:0)

除了@JGH的答案。

resumekubectl rollout undo deployment <name>中的规则将导致无限递归(Postgres 9.6)。

完整的(不可)运行示例:

INSERT