如果您可以使用 RULES 而不是用于插入的触发器,那么它可以返回正确的数字,但只能使用没有 WHERE 语句的单个 RULE。
参考1
参考2
参考文献3
另一种选择可能是创建一个“包装”分区表的视图,然后返回新行以指示成功的行更新,而不会意外向主表添加额外的不需要的行。
create view tablename_view as select * from tablename; -- create trivial wrapping view
CREATE OR REPLACE FUNCTION partitioned_insert_trigger() -- partitioned insert trigger
RETURNS TRIGGER AS $$
BEGIN
IF (NEW.partition_key>= 5500000000 AND
NEW.partition_key < 6000000000) THEN
INSERT INTO tablename_55_59 VALUES (NEW.*);
ELSIF (NEW.partition_key >= 5000000000 AND
NEW.partition_key < 5500000000) THEN
INSERT INTO tablename_50_54 VALUES (NEW.*);
ELSIF (NEW.partition_key >= 500000000 AND
NEW.partition_key < 1000000000) THEN
INSERT INTO tablename_5_9 VALUES (NEW.*);
ELSIF (NEW.partition_key >= 0 AND
NEW.partition_key < 500000000) THEN
INSERT INTO tablename_0_4 VALUES (NEW.*);
ELSE
RAISE EXCEPTION 'partition key is out of range. Fix the trigger function';
END IF;
RETURN NEW; -- RETURN NEW in this case, typically you'd return NULL from this trigger, but for views we return NEW
END;
$$
LANGUAGE plpgsql;
CREATE TRIGGER insert_view_trigger
INSTEAD OF INSERT ON tablename_view
FOR EACH ROW EXECUTE PROCEDURE partitioned_insert_trigger(); -- create "INSTEAD OF" trigger
参考:http ://www.postgresql.org/docs/9.2/static/trigger-definition.html
如果您使用视图包装器路线,则一种选择是也为删除和更新定义简单的“而不是”触发器,那么您可以在所有事务中使用视图表的名称代替普通表。
使用视图的另一个选项是创建一个插入规则,以便主表上的任何插入都转到视图[使用其触发器],例如(假设您已经partitioned_insert_trigger
创建了上面列出的 tablename_view 和 insert_view_trigger)
create RULE use_right_inserter_tablename AS
ON INSERT TO tablename
DO INSTEAD insert into tablename_view VALUES (NEW.*);
然后它将使用您的新工作视图包装插入。