postgres:2个表之间的约束

时间:2014-10-10 14:30:53

标签: sql database postgresql

我不确定我是否做得对,但问题是:

我想确保网络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'会延迟支票直到交易完成并且两次都改变了,但这种情况没有发生,我的理解是否正确?。

0 个答案:

没有答案