1

我想在我的应用程序中使用时间旅行功能(F.39. spi,PostgreSQL 9.1 文档),但它似乎对我来说不能正常工作。将行插入表中一切正常,我可以正确获取开始和停止日期,但是当我尝试更新这些行时,postgres 给了我关于违反 PRIMARY KEY 约束的错误。他试图插入一个与前一个元组具有相同主 ID 的元组......

从数据库中的所有表中删除主键约束是很疯狂的,但这是我需要的功能。所以也许你对时间旅行有一些经验?

任何形式的帮助将不胜感激。提前致谢。

DDL:

CREATE TABLE cities
(
  city_id serial NOT NULL, 
  state_id integer, 
  name character varying(80) NOT NULL,
  start_date abstime,
  stop_date abstime,
  CONSTRAINT pk_cities PRIMARY KEY (city_id ),
  CONSTRAINT fk_cities_states FOREIGN KEY (state_id)
      REFERENCES states (state_id) MATCH SIMPLE
      ON UPDATE CASCADE ON DELETE NO ACTION
)
WITH (
  OIDS=FALSE
);



-- Trigger: time_travel on cities

-- DROP TRIGGER time_travel ON cities;

CREATE TRIGGER time_travel
  BEFORE INSERT OR UPDATE OR DELETE
  ON cities
  FOR EACH ROW
  EXECUTE PROCEDURE timetravel('start_date', 'stop_date');

给出的声明:

INSERT INTO cities(
            state_id, name)
    VALUES (20,'Paris');

没关系。我得到 start_date 和 stop_date。但是通过:

UPDATE cities SET name='Rome' WHERE name='Paris'

我得到错误 - 前面描述过。

状态图式

-- Table: states

-- DROP TABLE states;

CREATE TABLE states
(
  state_id serial NOT NULL, -- unikatowy numer wojewodztwa
  country_id integer, -- identyfikator panstwa, w ktorym znajduje sie wojewodztwo
  name character varying(50), -- nazwa wojewodztwa
  CONSTRAINT pk_states PRIMARY KEY (state_id ),
  CONSTRAINT uq_states_state_id UNIQUE (state_id )
)
WITH (
  OIDS=FALSE
);

不幸的是,作为一个新用户,我不允许在这里发布图片。你可以在那里看到它们:

来自表格城市的样本数据:korpusvictifrew.cba.pl/postgres_cities.png

来自表状态的样本数据:korpusvictifrew.cba.pl/states_data.png

4

1 回答 1

2

时间旅行将 UPDATE 转换为旧记录的 stop_date 的 UPDATE 和 INSERT 的新记录,其中包含更改的数据和无穷大的 stop_date。由于 pk_cities,city_id 的记录不能超过一条。时间旅行触发器不允许您打破该要求。

你不能使用这个:

CONSTRAINT pk_cities PRIMARY KEY (city_id )

你必须使用这个

CONSTRAINT pk_cities PRIMARY KEY (city_id, stop_date)
于 2012-05-10T22:56:14.440 回答