Generic Postgres 9.5触发器将UPDATE转换为修改后的INSERT

时间:2016-01-20 04:12:23

标签: sql postgresql triggers

是否可以在Postgres 9.5中创建一个通用(非特定于表)触发器,该触发器将在instead of update上执行,将更新转换为插入?

基本上我想做的是(伪代码):

sql instead of UPDATE on TG_TABLE_NAME INSERT on TG_TABLE_NAME

我知道我可以创建一个特定于表的触发器,将每个值映射到insert语句中。我想要做的就是远离在每一张桌子上创建这个触发器。

1 个答案:

答案 0 :(得分:1)

这有点奇怪的想法(没什么个人的),但是这个怎么样:

CREATE FUNCTION not_update_but_insert() RETURNS trigger AS $$
BEGIN
  INSERT INTO TG_TABLE_NAME  -- Do an INSERT...
    SELECT NEW.*;            -- ... using the values from the row to be updated
  RETURN NULL;               -- Fail the UPDATE
END;
$$ LANGUAGE plpgsql;

显然,这对于具有PRIMARY KEY或其他UNIQUE约束的任何表都不起作用。对于每个适用的表,您必须CREATE TRIGGER x BEFORE UPDATE,因此在创建触发器之前分析表结构。

显然有一种解决办法 - 至少对于基于sequence的PK而言 - 通过检查information_schema对于"安全" TG_TABLE_NAME中的列,然后将它们的名称组合成字符串以拼接成INSERT语句(主语句列表和选择列表)。只需将列中包含序列或适当的默认值。但是,这并未解决没有明显替代的UNIQUE约束(如用户名或电子邮件地址)。