【问题标题】:Prohibit users from updating a column if another column is null?如果另一列为空,则禁止用户更新列?
【发布时间】:2019-01-21 12:21:12
【问题描述】:

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

我已经告诉人们,在为其分配project_id 值之前,他们不应将状态提升到 4 之后。自然人们不听,然后就会出现问题。

如果有人在 project_id 列是 null 时尝试从状态 4 更新到 5,有没有办法返回错误?我仍然需要人们能够将状态从 2 或 3 更新到状态 4,无论它是否具有 project_id

【问题讨论】:

    标签: sql postgresql triggers constraints


    【解决方案1】:

    如果您需要非常简单的检查,您可以按照@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();
    

    【讨论】:

      【解决方案2】:

      表上的检查约束怎么样:

      CHECK (project_id IS NOT NULL OR status < 5)
      

      【讨论】:

      • 如果数据还没有混乱,这似乎是可行的方法。它说行违反了检查。我将采用以下解决方案,谢谢
      • @Luffydude 如果数据已经搞砸了,你真的应该清理你的数据。首先放入新的约束/触发器,然后返回并清理数据。
      • @AleksG 如果你有时间清理 1k 行然后告诉我,人们最终会修复他们的数据。目前,下面建议的 NOT VALID 足以使您的查询正常工作
      【解决方案3】:

      如果你的数据违反了你想要的规则,你仍然可以使用CHECK constraint,就像sticky bit所展示的那样。就让它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;
      

      更多:

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2013-11-23
        • 2012-10-29
        • 1970-01-01
        • 2023-03-03
        • 1970-01-01
        相关资源
        最近更新 更多