2016-08-22 77 views
1

我试图按照建议here创建垂直分区表来存储时间序列数据。PostgreSQL继承表和插入触发器

到目前为止,我的模式是这样的:

CREATE TABLE events 
(
    topic text, 
    t timestamp, 
    value integer, 
    primary key(topic, t) 
); 

CREATE TABLE events_2014 
(
    primary key (topic, t), 
    check (t between '2014-01-01' and '2015-01-01') 
) INHERITS (events); 

现在,我想要创建一个INSTEAD OF INSERT触发器,使事件可以插在events表和行会在右边的分结束-表。但文件说,INSTEAD OF INSERT触发器只能创建上看法,并不表(或子表):

CREATE OR REPLACE FUNCTION insert_events() RETURNS TRIGGER AS $insert_events$ BEGIN 
    IF new.t between '2014-01-01' and '2015-01-01' THEN 
    INSERT INTO events_2014 SELECT new.*; 
    ... 
    END IF 
    RETURN NULL; 
END; 
$insert_events$ LANGUAGE PLPGSQL; 

CREATE TRIGGER insert_events INSTEAD OF INSERT ON events FOR EACH ROW EXECUTE PROCEDURE insert_events(); 
ERROR: "events" is a table 
DETAIL: Tables cannot have INSTEAD OF triggers. 

什么是这样做的正确方法吗?

+0

您在创建子表时似乎忘记了'INHERITS'子句。 –

+0

非常正确,谢谢,现在编辑。 – Tom

回答

2

您需要声明BEFORE INSERT触发器。

Documentation on partitioning是这方面知识的重要来源,并且充满了实例。从文档

CREATE OR REPLACE FUNCTION measurement_insert_trigger() 
RETURNS TRIGGER AS $$ 
BEGIN 
    IF (NEW.logdate >= DATE '2006-02-01' AND 
     NEW.logdate < DATE '2006-03-01') THEN 
     INSERT INTO measurement_y2006m02 VALUES (NEW.*); 
    ELSIF (NEW.logdate >= DATE '2006-03-01' AND 
      NEW.logdate < DATE '2006-04-01') THEN 
     INSERT INTO measurement_y2006m03 VALUES (NEW.*); 
    ... 
    ELSIF (NEW.logdate >= DATE '2008-01-01' AND 
      NEW.logdate < DATE '2008-02-01') THEN 
     INSERT INTO measurement_y2008m01 VALUES (NEW.*); 
    ELSE 
     RAISE EXCEPTION 'Date out of range. Fix the measurement_insert_trigger() function!'; 
    END IF; 
    RETURN NULL; 
END; 
$$ 
LANGUAGE plpgsql; 

实施例触发

实施例功能从文档

CREATE TRIGGER insert_measurement_trigger 
    BEFORE INSERT ON measurement 
    FOR EACH ROW EXECUTE PROCEDURE measurement_insert_trigger(); 

BEFORE从触发器返回NULL将保持父表是空的。

+0

完美,谢谢。 – Tom