我不确定我是否做得对,但问题是:
我想确保网络x [从1990年到2000年]只有站点[开始/结束时间在1990-2000之间]
CREATE TABLE network
(
id bigint NOT NULL,
alternate_code character varying(5),
code character varying(5) NOT NULL,
description character varying(250),
end_time timestamp with time zone,
historical_code character varying(5),
last_updated timestamp with time zone DEFAULT current_timestamp,
start_time timestamp with time zone NOT NULL,
version bigint,
CONSTRAINT network_pkey PRIMARY KEY (id),
CONSTRAINT unq_network_0 UNIQUE (code, start_time, end_time),
CONSTRAINT network_check CHECK (start_time < end_time)
)
WITH (
OIDS=FALSE
);
CREATE CONSTRAINT TRIGGER time_check_consistency
AFTER INSERT OR UPDATE
ON network
DEFERRABLE INITIALLY DEFERRED
FOR EACH ROW
EXECUTE PROCEDURE network_time_check_consistency();
CREATE OR REPLACE FUNCTION network_time_check_consistency()
RETURNS trigger AS
$BODY$
begin
RAISE NOTICE 'Message: % %',:new.id,:new.start_time;
IF EXISTS(select 1 from station where network_id= :new.id and (start_time < :new.start_time or end_time > :new.end_time)) THEN
RAISE EXCEPTION 'Invalid network time range (station out of range).';
END IF;
RETURN NULL;
END;
CREATE TABLE station
(
id bigint NOT NULL,
alternate_code character varying(5),
code character varying(5) NOT NULL,
creation_time timestamp with time zone,
description character varying(255),
elevation numeric(7,1) NOT NULL,
end_time timestamp with time zone,
geology character varying(255),
historical_code character varying(5),
last_updated timestamp with time zone DEFAULT current_timestamp,
latitude numeric(8,6) NOT NULL,
longitude numeric(9,6) NOT NULL,
start_time timestamp with time zone NOT NULL,
termination_time timestamp with time zone,
vault character varying(255),
version bigint,
network_id bigint NOT NULL,
station_id bigint,
CONSTRAINT station_pkey PRIMARY KEY (id),
CONSTRAINT fk_station_network_id FOREIGN KEY (network_id)
REFERENCES network (id) MATCH SIMPLE
ON UPDATE NO ACTION ON DELETE NO ACTION,
CONSTRAINT fk_station_station_id FOREIGN KEY (station_id)
REFERENCES site (id) MATCH SIMPLE
ON UPDATE NO ACTION ON DELETE NO ACTION,
CONSTRAINT unq_station_0 UNIQUE (network_id, code, start_time, end_time),
CONSTRAINT station_check CHECK (start_time < end_time),
CONSTRAINT station_latitude_check CHECK ((90::numeric >= latitude)::smallint >= (-90)),
CONSTRAINT station_longitude_check CHECK ((180::numeric >= longitude)::smallint >= (-180))
)
WITH (
OIDS=FALSE
);
CREATE CONSTRAINT TRIGGER time_check_consistency
AFTER INSERT OR UPDATE
ON station
DEFERRABLE INITIALLY DEFERRED
FOR EACH ROW
EXECUTE PROCEDURE station_time_check_consistency();
CREATE OR REPLACE FUNCTION station_time_check_consistency()
RETURNS trigger AS
$BODY$
begin
IF EXISTS(select 1 from channnel where station_id= station_in_id and (start_time < in_starttime or end_time > in_endtime)) THEN
RAISE EXCEPTION 'Invalid station time range (channel[s] out of range).';
END IF;
IF EXISTS(select 1 from network where id= network_in_id and (start_time > in_starttime or end_time < in_endtime)) THEN
RAISE EXCEPTION 'Invalid station time range (network out of range).';
END IF;
RETURN NULL;
END;
如果我这样做:
begin
update network set start_time='1990-01-01' where id=44201;
RAISE NOTICE 'FINISHED 1...';
update station set start_time='1991-01-01' where id=44202;
RAISE NOTICE 'FINISHED 2...';
commit;
end;
我明白了:
ERROR: Invalid network time range (station out of range).
CONTEXT: edb-spl function inline_code_block line 6 at COMMIT
我认为'DEFERRABLE INITIALLY DEFERRED'会延迟支票直到交易完成并且两次都改变了,但这种情况没有发生,我的理解是否正确?。