假设我有以下表格和视图:
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;
我希望能够插入到视图中,因此我创建了以下函数并触发:
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();
现在我想只在视图中还没有field_x的行时才将值插入到视图中,例如:
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行为从视图插入到表插入中涟漪吗? (我可能希望稍后指定不同的冲突行为,所以如果我可以避免,我不想在触发器功能中对其进行硬编码。)
谢谢!
答案 0 :(得分:0)
我仍然不确定如果我理解你的话。但我试试:
如果你改变了
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;
我认为您只能对具有唯一约束的表使用ON CONFLICT
,因此,当您指定constraint_name的target_name
ON CONFLICT DO NOTHING
并失败