在一个语句中将相同的UUID插入两个表(一次作为主键,一次作为外键)

时间:2015-01-22 23:09:48

标签: postgresql

考虑postgres视图,它将两个表table_geomtable_data连接在一起id_data字段id_datatable_data的主键和外国字符键入table_geom):

CREATE OR REPLACE VIEW myschema.view AS 
 SELECT table_geom.geom, table_geom.id_geom, table_geom.id_data,
        table_data.id_data, table_data.data
 FROM myschema.table_geom, myschema.table_data
 WHERE table_geom.id_data = table_data.id_data;

id_geomid_data是UUID。我想使用uuid_generate_v4()使用

等规则在插入时自动生成它们
CREATE OR REPLACE RULE view_insert_rule AS
  ON INSERT TO myschema.view DO INSTEAD (
    INSERT INTO myschema.table_geom (geom, id_geom, id_data) VALUES (new.geom, (select uuid_generate_v4()), $ID_DATA$);
    INSERT INTO myschema.table_data (id_data, data) VALUES ($ID_DATA$, new.data);
  );

问题:插入两个表时,$ID_DATA$需要是相同的UUID。

一次尝试

CREATE OR REPLACE RULE view_insert_rule AS
  ON INSERT TO myschema.view DO INSTEAD (
    WITH ins_data as (
      INSERT INTO myschema.table_data (id_data, data) VALUES ((select uuid_generate_v4()), new.data) RETURNING id_data
    )
    INSERT INTO myschema.table_geom (geom, id_geom, id_data) VALUES (new.geom, (select uuid_generate_v4()), ins_data.id_data);
  );

但由于ERROR: cannot refer to NEW within WITH query而无效。

知道怎么写这样的插入规则吗?

1 个答案:

答案 0 :(得分:2)

由于您在视图上执行INSERT,因此建议的过程是视图上的INSTEAD OF INSERT触发器。在触发器函数中,您将视图上的插入重写为基础表上的两个插入:

CREATE FUNCTION insert_new_uuids() RETURNS trigger AS $$
DECLARE
  new_id uuid;
BEGIN
  new_id := uuid_generate_v4();
  INSERT INTO myschema.table_data (id_data, data) VALUES (new_id, NEW.data);
  INSERT INTO myschema.table_geom (geom, id_geom, id_data) VALUES (NEW.geom, uuid_generate_v4(), new_id);
  RETURN NEW;
END;
$$ LANGUAGE plpgsql;

CREATE TRIGGER ins_view
INSTEAD OF INSERT ON myschema."view"
FOR EACH ROW EXECUTE PROCEDURE insert_new_uuids();