当前位置: 首页 > 知识库问答 >
问题:

PostgreSQL 9.5 UPSERT IN RULE

康秋月
2023-03-14

我在可更新的视图系统中有一个 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;

但是,由于这三列可以有许多不同的组合,我不认为我可以设置一个包含所有列的约束(尽管我可能在SQL逻辑中遗漏了一点理解),因此取消了CONFLIT DO NOTHING部分。

理想的解决方案似乎是使用 EXCEPT,但它仅适用于“插入到 SELECT”语句中。有没有办法使用插入到 SELECT 语句中引用新插入的行?像从新巴尔斯(在我的情况下)?

如果不是,我可以想象一个地方不存在的条件,但同样的问题比以前出现。

我猜这是一个相当常见的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个答案

梁丘赞
2023-03-14

插入规则中的插入将导致无穷大递归(后 9.6)。

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

CREATE SCHEMA ttest;

CREATE TABLE ttest.table_1 (
  id bigserial
    CONSTRAINT pk_table_1 PRIMARY KEY,
  col_1 text,
  col_2 text
);

CREATE OR REPLACE RULE table_1_always_upsert AS
ON INSERT TO ttest.table_1
DO INSTEAD (
  INSERT INTO ttest.table_1(id, col_1, col_2)
    VALUES (new.id, new.col_1, new.col_2)
  ON CONFLICT ON CONSTRAINT pk_table_1
    DO UPDATE
    SET col_1 = new.col_1,
      col_2 = new.col_2
);

INSERT INTO ttest.table_1(id, col_1, col_2)  -- will result error: infinity recursion in rules
  VALUES (1, 'One', 'A'),
         (2, 'Two', 'B');

INSERT INTO ttest.table_1(id, col_1, col_2)
  VALUES (1, 'One_updated', 'A_updated'),
         (2, 'Two_updated', 'B_updated'),
         (3, 'Three_inserted', 'C_inserted');

SELECT *
FROM ttest.table_1;
魏翔
2023-03-14

你如何定义唯一性?如果是名称代码区的组合,那么只需在表geo_pays_gex.voie上添加一个约束uniQUE(name, code, District)。3加在一起必须是唯一的…但是你可以有几次相同的名字、代码或地区。

http://rextester.com/EWR73154看

编辑 ***

因为可以有空值,并且希望将它们视为唯一值,所以可以用替换空值的唯一索引来替换约束创建

CREATE UNIQUE INDEX
voie_uniq ON voie
(COALESCE(name,''), code, COALESCE(district,''));
 类似资料:

相关问答

相关文章

相关阅读