postgresql - 如何应用 'advanced' 基于查询的约束?

标签 postgresql

我找不到应用“高级”基于查询的约束的方法。

例如,对于以下虚构架构,我如何强制 Bob 日常事件的总百分比不超过 100%?

我已经研究过 trigger constraints但我不认为他们会做我想做的事(如果满足某些条件则中止插入/更新)。

感谢您阅读我的问题以及您可以提供的任何帮助。

create table employee (
    id serial PRIMARY KEY,
    name varchar(100) NOT NULL
);

create table work_day (
    employee_id integer references employee(id) NOT NULL,
    percentage integer NOT NULL CHECK (percentage > 0 and percentage <= 100),
    activity varchar(100) NOT NULL
);

INSERT INTO employee (name) VALUES ('bob');

-- Bob spends 50% of the day slacking, 20% eating and 30% working (total = 100%)
INSERT INTO work_day (employee_id, percentage, activity) VALUES (1, 50, 'slacking'); 
INSERT INTO work_day (employee_id, percentage, activity) VALUES (1, 20, 'eating');
INSERT INTO work_day (employee_id, percentage, activity) VALUES (1, 30, 'working');

-- This should be invalid!!! 100% of Bob's time has already been allocated
INSERT INTO work_day (employee_id, percentage, activity) VALUES (1, 10, 'invalid');

最佳答案

我已经测试了这段代码并且它有效:

CREATE OR REPLACE FUNCTION check_work_day_percentage() RETURNS trigger AS $$
    BEGIN
        IF coalesce((select sum(percentage) 
                    from work_day
                    where employee_id = NEW.employee_id
                    and activity != NEW.activity), 0) 
                + coalesce(NEW.percentage, 0) > 100 THEN
            RAISE EXCEPTION 'Employee % exceeds 100 percent', NEW.employee_id;
        END IF;
        RETURN NEW;
    END;
$$ LANGUAGE plpgsql;

CREATE TRIGGER work_day_trigger 
BEFORE INSERT OR UPDATE ON work_day
FOR EACH ROW EXECUTE PROCEDURE check_work_day_percentage();

仅供引用,表约束不会这样做:根据 docs ,

Currently, CHECK expressions cannot contain subqueries nor refer to variables other than columns of the current row.

关于postgresql - 如何应用 'advanced' 基于查询的约束?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6276810/

相关文章:

postgresql - 使用触发器更新新创建的行值

ruby - 使用 Sequel 设置主键初始值

php - 是否可以在codeigniter中连接两个dbms MySQL和postgresQL?

javascript - 获取postgres-query的结果作为nodejs中的变量

mysql - 数据库 SQL 兼容性

java - 如何启动 postgresql 实例进行集成测试

postgresql - 如何限制postgresql中的行数

postgresql - 带有 CTE 的 Postgres EXECUTE

java - 关系 OneToOne 的 PSQLException : relation "car_model" does not exist

postgresql - Postgres 时间戳索引性能