Таблица, унаследованная PostgreSQL, всегда возвращает строку с нулевым значением
-
23-09-2019 - |
Вопрос
Я имею в виду http://www.if-not-true-then-false.com/2009/11/howto-create-postgresql-table-partitioning-part-1/
Чтобы воспроизвести проблему, выполните несколько простых шагов:
(1) создать базу данных с именем «учебник».
(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;
(3) создайте базу данных с именем «tutorial_partition»
(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_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();
(5) выполнить
SELECT * FROM insert_table() on tutorial
Мы получаем
УВЕДОМЛЕНИЕ:После вставки возвращаемый идентификатор рекламодателя равен 1.
(6) выполнить
SELECT * FROM insert_table() on tutorial_partition
Мы получаем
УВЕДОМЛЕНИЕ:После вставки возвращаемый идентификатор рекламодателя равен
Как можно получить, чтобы рекламодатель_id тоже был равен 1 в обучающем_разделе?
Решение
Триггер возвращает NULL, что указывает INSERT, что никаких действий выполнять не нужно.Поскольку никаких действий не выполняется, предложение RETURNING * ничего не возвращает.Вы не сможете перехватить (и переопределить) INSERT и используйте RETURNING в той же операции и получите что-нибудь значимое.