我想在我的应用程序中使用timetravel函数(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
答案 0 :(得分:1)
时间旅行将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)