【问题标题】:Trigger before insert into increments sequence by 2在插入增量序列之前触发 2
【发布时间】:2017-08-30 09:17:18
【问题描述】:

我使用的是 PostgreSQL 9.6。我有以下序列和表格:

CREATE SEQUENCE measure_id_seq
    INCREMENT 1
    MINVALUE 1
    MAXVALUE 9223372036854775807
    START 1
    CACHE 1;

CREATE TABLE measure (
    id integer NOT NULL DEFAULT nextval('measure_id_seq'::regclass),
    time_stp timestamp with time zone NOT NULL,
    val double precision NOT NULL,
    pollutant character varying(255) NOT NULL,
    station character varying(255) NOT NULL,
    CONSTRAINT measure_pkey PRIMARY KEY (id)
)
WITH (
    OIDS=FALSE
);

“measure”表根据“pollutant”和“station”列的值划分为不同的表。

为此,我有一个在将新数据插入表之前执行的触发器:

CREATE OR REPLACE FUNCTION before_insert_on_measure()
RETURNS TRIGGER LANGUAGE plpgsql as $$

DECLARE format_station TEXT := lower(replace(new.station, ' ', ''));
DECLARE format_pollutant TEXT := lower(replace(new.pollutant, ' ', ''));
BEGIN
    EXECUTE format(
        $f$
            CREATE TABLE IF NOT EXISTS %I (
            check (station = %L AND pollutant = %L)
            ) INHERITS (measure)
        $f$, 
        concat('partition_measure_', format_station, '_', format_pollutant), 
        new.station,
        new.pollutant);
    EXECUTE format(
        $f$
            INSERT INTO %I (time_stp, val, pollutant, station)
            VALUES (%L, %L, %L, %L)
        $f$, 
        concat('partition_measure_', format_station, '_', format_pollutant), 
        new.time_stp,
        new.val,
        new.pollutant,
        new.station
        );
    RETURN NULL;
END $$;

CREATE TRIGGER before_insert_on_measure
    BEFORE INSERT ON measure
    FOR EACH ROW EXECUTE PROCEDURE before_insert_on_measure();

将新数据插入“measures”表会创建正确的子表。例如当我插入以下数据时:

INSERT INTO measure (time_stp, val, pollutant, station)
    VALUES ('2015-01-01 01:00:00', 32.4, 'O3', 'Station 1');
INSERT INTO measure (time_stp, val, pollutant, station)
    VALUES ('2016-01-01 01:00:00', 54, 'NO2', 'Station 2');

它创建表格:

  • partition_measure_station1_o3
  • partition_measure_station2_no2

我遇到的问题是我的“id”列增加了 2

id time_stp                 val  pollutant station
2  "2015-01-01 01:00:00+04" 32.4 "O3"      "Station 1"
4  "2016-01-01 01:00:00+04" 54   "NO2"     "Station 2"

相反,我想要:

id ...
1 ...
2 ...

nextval('measure_id_seq') 似乎在每个 INSERT 上执行了两次。

有什么建议吗?

编辑:JGH 提供的答案是正确的。作为参考,这里是编辑的触发器:

CREATE OR REPLACE FUNCTION before_insert_on_measure()
RETURNS TRIGGER LANGUAGE plpgsql as $$

DECLARE format_station TEXT := lower(replace(new.station, ' ', ''));
DECLARE format_pollutant TEXT := lower(replace(new.pollutant, ' ', ''));
BEGIN
    EXECUTE format(
        $f$
            CREATE TABLE IF NOT EXISTS %I (
            check (station = %L AND pollutant = %L)
            ) INHERITS (measure)
        $f$, 
        concat('partition_measure_', format_station, '_', format_pollutant), 
        new.station,
        new.pollutant);
    EXECUTE format(
        $f$
            INSERT INTO %I
            VALUES (%L, %L, %L, %L, %L)
        $f$, 
        concat('partition_measure_', format_station, '_', format_pollutant), 
        new.id,
        new.time_stp,
        new.val,
        new.pollutant,
        new.station
        );
    RETURN NULL;
END $$;

CREATE TRIGGER before_insert_on_measure
    BEFORE INSERT ON measure
    FOR EACH ROW EXECUTE PROCEDURE before_insert_on_measure();

【问题讨论】:

    标签: postgresql


    【解决方案1】:

    在触发器中,当您对分区表执行插入语句时,您必须传递 new.id 值。如果不这样做,则使用默认值,即对序列生成器的第二次调用。

    【讨论】:

      猜你喜欢
      • 2015-02-14
      • 2012-12-11
      • 2011-08-24
      • 1970-01-01
      • 2023-04-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多