PostgreSQL继承表始终返回空值行

PostgreSQL继承表始终返回空值行,postgresql,triggers,Postgresql,Triggers,我指的是 要重现此问题,以下是一些简单的步骤: (1) 创建名为“tutorial”的数据库 (2) 执行以下SQL查询: CREATE TABLE impressions_by_day ( advertiser_id SERIAL NOT NULL, day DATE NOT NULL DEFAULT CURRENT_DATE, impressions INTEGER NOT NULL, PRIMARY KEY (advertiser_id, day)

我指的是

要重现此问题,以下是一些简单的步骤:

(1) 创建名为“tutorial”的数据库

(2) 执行以下SQL查询:

CREATE TABLE impressions_by_day (
    advertiser_id SERIAL NOT NULL,
    day DATE NOT NULL DEFAULT CURRENT_DATE,
    impressions INTEGER NOT NULL,
        PRIMARY KEY (advertiser_id, day)
);

CREATE OR REPLACE FUNCTION insert_table()
  RETURNS void AS
$BODY$DECLARE
    _impressions_by_day impressions_by_day;
BEGIN
    INSERT INTO impressions_by_day(impressions ) VALUES(888) RETURNING  * INTO _impressions_by_day;

    RAISE NOTICE 'After insert, the returned advertiser_id is %', _impressions_by_day.advertiser_id;
END;$BODY$
  LANGUAGE 'plpgsql' VOLATILE;
ALTER FUNCTION insert_table() OWNER TO postgres;
CREATE TABLE impressions_by_day (
    advertiser_id SERIAL NOT NULL,
    day DATE NOT NULL DEFAULT CURRENT_DATE,
    impressions INTEGER NOT NULL,
        PRIMARY KEY (advertiser_id, day)
);

CREATE OR REPLACE FUNCTION insert_table()
  RETURNS void AS
$BODY$DECLARE
    _impressions_by_day impressions_by_day;
BEGIN
    INSERT INTO impressions_by_day(impressions ) VALUES(888) RETURNING  * INTO _impressions_by_day;

    RAISE NOTICE 'After insert, the returned advertiser_id is %', _impressions_by_day.advertiser_id;
END;$BODY$
  LANGUAGE 'plpgsql' VOLATILE;
ALTER FUNCTION insert_table() OWNER TO postgres;

CREATE TABLE impressions_by_day_y2010m1ms2 (
    PRIMARY KEY (advertiser_id, day), 
    CHECK ( day >= DATE '2010-01-01' AND day < DATE '2010-03-01' )
) INHERITS (impressions_by_day);


CREATE INDEX impressions_by_day_y2010m1ms2_index ON impressions_by_day_y2010m1ms2 (day);


CREATE OR REPLACE FUNCTION impressions_by_day_insert_trigger()
RETURNS TRIGGER AS $$
BEGIN
    IF ( NEW.day >= DATE '2010-01-01' AND NEW.day < DATE '2010-03-01' ) THEN 
        INSERT INTO impressions_by_day_y2010m1ms2 VALUES (NEW.*); 
    ELSE
        RAISE EXCEPTION 'Date out of range.  Something wrong with the impressions_by_day_insert_trigger() function!';
    END IF;
    RETURN NULL;
END;
$$
LANGUAGE plpgsql;

CREATE TRIGGER insert_impressions_by_day_trigger 
    BEFORE INSERT ON impressions_by_day 
    FOR EACH ROW EXECUTE PROCEDURE impressions_by_day_insert_trigger();
(3) 创建名为“教程分区”的数据库

(4) 执行以下SQL查询:

CREATE TABLE impressions_by_day (
    advertiser_id SERIAL NOT NULL,
    day DATE NOT NULL DEFAULT CURRENT_DATE,
    impressions INTEGER NOT NULL,
        PRIMARY KEY (advertiser_id, day)
);

CREATE OR REPLACE FUNCTION insert_table()
  RETURNS void AS
$BODY$DECLARE
    _impressions_by_day impressions_by_day;
BEGIN
    INSERT INTO impressions_by_day(impressions ) VALUES(888) RETURNING  * INTO _impressions_by_day;

    RAISE NOTICE 'After insert, the returned advertiser_id is %', _impressions_by_day.advertiser_id;
END;$BODY$
  LANGUAGE 'plpgsql' VOLATILE;
ALTER FUNCTION insert_table() OWNER TO postgres;
CREATE TABLE impressions_by_day (
    advertiser_id SERIAL NOT NULL,
    day DATE NOT NULL DEFAULT CURRENT_DATE,
    impressions INTEGER NOT NULL,
        PRIMARY KEY (advertiser_id, day)
);

CREATE OR REPLACE FUNCTION insert_table()
  RETURNS void AS
$BODY$DECLARE
    _impressions_by_day impressions_by_day;
BEGIN
    INSERT INTO impressions_by_day(impressions ) VALUES(888) RETURNING  * INTO _impressions_by_day;

    RAISE NOTICE 'After insert, the returned advertiser_id is %', _impressions_by_day.advertiser_id;
END;$BODY$
  LANGUAGE 'plpgsql' VOLATILE;
ALTER FUNCTION insert_table() OWNER TO postgres;

CREATE TABLE impressions_by_day_y2010m1ms2 (
    PRIMARY KEY (advertiser_id, day), 
    CHECK ( day >= DATE '2010-01-01' AND day < DATE '2010-03-01' )
) INHERITS (impressions_by_day);


CREATE INDEX impressions_by_day_y2010m1ms2_index ON impressions_by_day_y2010m1ms2 (day);


CREATE OR REPLACE FUNCTION impressions_by_day_insert_trigger()
RETURNS TRIGGER AS $$
BEGIN
    IF ( NEW.day >= DATE '2010-01-01' AND NEW.day < DATE '2010-03-01' ) THEN 
        INSERT INTO impressions_by_day_y2010m1ms2 VALUES (NEW.*); 
    ELSE
        RAISE EXCEPTION 'Date out of range.  Something wrong with the impressions_by_day_insert_trigger() function!';
    END IF;
    RETURN NULL;
END;
$$
LANGUAGE plpgsql;

CREATE TRIGGER insert_impressions_by_day_trigger 
    BEFORE INSERT ON impressions_by_day 
    FOR EACH ROW EXECUTE PROCEDURE impressions_by_day_insert_trigger();
我们得到

注意:插入后,返回的广告客户id为1

(6) 执行

我们得到

注意:插入后,返回的广告客户id为


在教程分区中,如何才能使广告客户id也为1?

触发器传回NULL,这向插入程序指示不执行任何操作。由于没有执行任何操作,RETURNING*子句不返回任何内容。您将无法在同一操作中截取(并覆盖)插入和使用返回并获得任何有意义的内容。

但是。。。我现在正在实现表分区。我希望确保父表“unit”为空,并且“unit\u 0”已填充。但是,我的所有查询都可以通过父表“unit”执行。我指的是触发器,总体方法是好的。您将无法使用RETURNING返回id值,因为returnnull强制RETURNING*解析为no data(因为插入本身没有完成)。也就是说,您可以使用规则而不是触发器来实现这一点。可能是这样的:在INSERT TO unit DO上创建规则分区,而不是从以前的_trigger_func(NEW.fk_lot_id,NEW.cycle)中选择*;然后更改函数以返回所需的数据。我并不是说这会奏效,但值得一试。你能给我举个关于规则的例子吗?:)好啊我放弃使用触发器功能。但是在一个过程函数中有if…table…exist检查。