postgresql - 带有 INSTEAD OF 触发器的 Postgres INSERT ON CONFLICT 行为

标签 postgresql view triggers insert

假设我有以下表格和 View :

CREATE TABLE table_a(
    field_x INTEGER PRIMARY KEY,
    id SERIAL UNIQUE
);
CREATE TABLE table_b(
    a_id INTEGER PRIMARY KEY REFERENCES table_a(id),
    field_y INTEGER NOT NULL
);
CREATE VIEW v AS SELECT * FROM table_a JOIN table_b ON table_a.id=table_b.a_id;

我希望能够插入到 View 中,所以我创建了以下函数和触发器:

CREATE FUNCTION insert_into_view()
RETURNS TRIGGER
LANGUAGE plpgsql
AS $function$
   DECLARE new_id INTEGER;
   BEGIN
      IF TG_OP = 'INSERT' THEN
        INSERT INTO table_a (field_x) VALUES (NEW.field_x) ON CONFLICT DO NOTHING RETURNING id INTO new_id;
        IF new_id IS NULL THEN
          SELECT id FROM table_a WHERE field_x=NEW.field_x INTO new_id;
        END IF;
        INSERT INTO table_b (a_id, field_y) VALUES (new_id, NEW.field_y);
      END IF;
      RETURN NEW;
    END;
$function$;
CREATE TRIGGER view_insert_trigger
    INSTEAD OF INSERT ON
      v FOR EACH ROW EXECUTE PROCEDURE insert_into_view();

现在我只想在 View 中不存在 field_x 的行时才将值插入 View ,例如:

INSERT INTO v (field_x, field_y) VALUES (5,6);
INSERT INTO v (field_x, field_y) VALUES (5,8) ON CONFLICT DO NOTHING;

我希望第二个插入静静地什么都不做。但是,我明白了:

ERROR:  duplicate key value violates unique constraint "table_b_pkey"
DETAIL:  Key (a_id)=(2) already exists.
CONTEXT:  SQL statement "INSERT INTO table_b (a_id, field_y) VALUES (new_id, NEW.field_y)"

我知道为什么会出现此错误:函数 insert_into_view 在插入 table_b 时未指定 ON CONFLICT 行为,默认情况下查询失败。因此我的问题是:我可以使 ON CONFLICT 行为从 View 插入波纹到表插入吗? (我可能想在以后指定不同的冲突行为,所以如果可以避免的话,我不想在触发器函数中对其进行硬编码。)

谢谢!

最佳答案

我仍然不确定我是否理解正确。但我尝试:

如果你改变

INSERT INTO table_b (a_id, field_y) VALUES (new_id, NEW.field_y)

INSERT INTO table_b (a_id, field_y) VALUES (new_id, NEW.field_y) ON CONFLICT DO NOTHING

在函数中它将开始静默工作。

关于

INSERT INTO v (field_x, field_y) VALUES (5,8) ON CONFLICT DO NOTHING;

我认为您只能在具有唯一约束的表、so 和外部表上使用 ON CONFLICT,而规则将忽略 ON CONFLICT DO NOTHING 并在您指定时失败约束名称的目标名称

关于postgresql - 带有 INSTEAD OF 触发器的 Postgres INSERT ON CONFLICT 行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44528835/

相关文章:

sql - 使用每行返回两个值的函数插入

javascript - 触发 "onchange"事件

mysql - 我可以在 MySQL 触发器中使用类似事务的功能吗

sql - 根据postgresql中的组角色过滤查询行

postgresql - 如何关闭旧 Cloud Run 修订版的 SQL 连接?

java - 有什么方法可以从 Eclipse 的层次结构 View 中隐藏测试类吗?

android - 从在 Android 中以编程方式创建的父 View 中查找 subview

php - 在 View 内的函数中访问 Codeigniter 数据变量

mysql - 如何在表上创建插入触发器?

python - django.db.utils.DataError : numeric field overflow - django 错误