如果另一列为空,则禁止用户更新一列?

时间:2019-01-21 12:21:12

标签: sql postgresql triggers constraints

我有mytable,它具有3个整数字段:idstatusproject_id

我已经告诉人们在分配project_id值之前,他们不应将状态提高到4以上。人们自然不会听,然后便会遇到问题。

如果有人在project_id列为null的情况下尝试从状态4更新为5,是否可以返回错误?我仍然需要人们能够将状态从2或3更新为状态4,无论它是否具有project_id

3 个答案:

答案 0 :(得分:5)

如果您需要非常简单的检查,则可以按照@stickbit的建议使用CHECK constraint

如果您需要更复杂的逻辑,则可以使用TRIGGER functionality

CREATE FUNCTION check_status()
  RETURNS trigger AS
$mytrigger$
BEGIN
   IF OLD.status = 4 AND NEW.status >= 5 AND NEW.project_id IS NULL THEN
      RAISE EXCEPTION 'Project ID must be assigned before progressing to status 5';
   END IF;
   RETURN NEW;
END
$mytrigger$
LANGUAGE plpgsql;

CREATE TRIGGER project_id_check
BEFORE UPDATE ON "MyTable"
FOR EACH ROW EXECUTE PROCEDURE check_status();

答案 1 :(得分:2)

关于表的检查约束如何:

CHECK (project_id IS NOT NULL OR status < 5)

答案 2 :(得分:2)

如果您的数据违反了所需的规则,则仍然可以使用CHECK constraint,如粘性位所示。只需使其NOT VALID即可:

ALTER TABLE mytable ADD CONSTRAINT project_id_required_for_status_5_or_higher
CHECK project_id IS NOT NULL OR status < 5) NOT VALID;

然后,该约束仅应用于后续的插入和更新。现有行将被忽略。 (但是任何新更新必须解决违反值的问题,否则将失败。)

您还应该具有FOREIGN KEY constraint来强制执行project_id的参照完整性,否则可以通过伪值轻松地规避该约束。

重点:CHECK约束不仅禁止您提到的更新,而且插入时也带有违规状态。

所有行都固定为符合新规则后,就可以VALIDATE约束:

ALTER TABLE mytable VALIDATE CONSTRAINT project_id_required_for_status_5_or_higher;

更多: