检查最后一个最大值的约束
Check constraint on last max
如何对字段中的最后一个最大值进行检查约束?例如,在下面:
CREATE TABLE prisoner (
prisoner_id SERIAL4 PRIMARY KEY,
name TEXT NOT NULL CHECK(length(name) <= 256)
);
CREATE TABLE meals (
prisoner_id INT4 REFERENCES prisoner,
last_meal_time TIMESTAMP(6) WITH TIME ZONE NOT NULL DEFAULT now()
);
如何确保 last_meal_time
始终比给定 prisoner_id
的最后一个最大值 last_meal_time
>=
?换句话说,我将无法追溯地给任何给定的囚犯喂另一顿饭。
设置主键:
create table meals (
prisoner_id int4 references prisoner,
last_meal_time timestamp with time zone not null default clock_timestamp(),
primary key (prisoner_id, last_meal_time)
);
注意是clock_timestamp
.
并始终插入默认值:
insert into meals (prisoner_id) values (1);
您可以在检查约束中使用函数,例如:
create table t(id serial, p int, ts timestamp);
create function t_max_time(p_id int) returns timestamp as $$ select max(ts) from t where p = p_id $$ language sql;
alter table t add constraint t_ts_check check (ts >= t_max_time(p));
-- Thanks to Clodoaldo Neto attention,
-- To prevent changes in other concurrent transactions while our transaction is active we can lock table for exclusive editing like:
lock table t in exclusive mode nowait;
-- It locks table or raises exception if table already locked by another transaction
insert into t(p, ts) values (1, '2016-02-02 10:10:10'), (1, '2016-02-02 11:11:11'); -- It works
insert into t(p, ts) values (1, '2016-02-02 09:09:09'); -- Constraint violation
如何对字段中的最后一个最大值进行检查约束?例如,在下面:
CREATE TABLE prisoner (
prisoner_id SERIAL4 PRIMARY KEY,
name TEXT NOT NULL CHECK(length(name) <= 256)
);
CREATE TABLE meals (
prisoner_id INT4 REFERENCES prisoner,
last_meal_time TIMESTAMP(6) WITH TIME ZONE NOT NULL DEFAULT now()
);
如何确保 last_meal_time
始终比给定 prisoner_id
的最后一个最大值 last_meal_time
>=
?换句话说,我将无法追溯地给任何给定的囚犯喂另一顿饭。
设置主键:
create table meals (
prisoner_id int4 references prisoner,
last_meal_time timestamp with time zone not null default clock_timestamp(),
primary key (prisoner_id, last_meal_time)
);
注意是clock_timestamp
.
并始终插入默认值:
insert into meals (prisoner_id) values (1);
您可以在检查约束中使用函数,例如:
create table t(id serial, p int, ts timestamp);
create function t_max_time(p_id int) returns timestamp as $$ select max(ts) from t where p = p_id $$ language sql;
alter table t add constraint t_ts_check check (ts >= t_max_time(p));
-- Thanks to Clodoaldo Neto attention,
-- To prevent changes in other concurrent transactions while our transaction is active we can lock table for exclusive editing like:
lock table t in exclusive mode nowait;
-- It locks table or raises exception if table already locked by another transaction
insert into t(p, ts) values (1, '2016-02-02 10:10:10'), (1, '2016-02-02 11:11:11'); -- It works
insert into t(p, ts) values (1, '2016-02-02 09:09:09'); -- Constraint violation