在数据已经不正确的postgres表中添加检查

问题描述 投票:1回答:2

这对我来说似乎是一个有用的问题,在任何地方都找不到任何书面信息,以为这可能太明显了。只想确认一下:

如果我更改一个postgres表以添加检查,但是已经存在的数据与此检查不一致,那么什么也不会发生,对吧? Postgres将仅检查添加检查后插入/更新的数据吗?

假设某行的生日年份列值为1987。如果我添加一个支票作为生日年份> 1990,并且我从不更新此字段,但我又更新了该行中的其他字段,该怎么办。我可以更新此行吗?如果没有,那么有一种方法可以添加检查,这样我就可以在不检查的情况下更新所有旧行,但是会影响到新添加的行,基本上只对插入查询而不是对更新查询添加检查?希望我的问题清楚易懂。

sql postgresql database-trigger check-constraints
2个回答
1
投票

检查约束会检查表中已经存在的值,如果有违反条件的行将无法创建。这就是约束的关键,断言数据满足条件。

为了防止新数据违反条件,您可以做的是创建一个触发器,对其进行检查并在违反条件时引发错误。类似于以下内容:

CREATE FUNCTION check_birthyear
                ()
                RETURNS TRIGGER
AS
$$
BEGIN
  IF NOT new.birthyear > 1990 THEN
    RAISE EXCEPTION 'birthyear must be greater than 1990';
  END IF;

  RETURN new;
END;
$$
LANGUAGE plpgsql;

CREATE TRIGGER elbat_check_birthyear
               BEFORE INSERT
               ON elbat
               FOR EACH ROW
               EXECUTE PROCEDURE check_birthyear();

db<>fiddle

但是您应该真正考虑一下。问自己,您是否真的希望旧数据违反条件。仅仅清除旧的和有故障的数据可能比保留它们更好。否则,您将无法确定某一行会满足的条件。


0
投票

PostgreSQL不知道新行中的旧行,因此您无法获得仅允许对旧行进行违规的约束。

正如在另一个答案中所解释的,如果创建约束,则会检查现有行的有效性。

存在一个例外,该例外允许您在包含违反条件的行的表上创建CHECK约束:将约束创建为NOT VALID。然后将不检查现有行的合规性。

但是,正如开头所说,只有在新行版本满足条件的情况下,才允许对旧行进行修改。

[一种替代的想法是添加类型为old的新列boolean,以区分旧行和新行。然后,您可以在检查条件中明确排除旧行。

© www.soinside.com 2019 - 2024. All rights reserved.