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

mm9b1k5b  于 2021-07-26  发布在  Java
关注(0)|答案(2)|浏览(331)

这似乎是一个有用的问题,我没有找到任何书面资料,所以认为这可能是太明显了。我只想确认一下:
如果我修改postgres表来添加一个检查,但是已经存在的数据与这个检查不一致,那么它不会发生任何变化,对吗?postgres将只检查添加检查后插入/更新的数据?
假设某行的生日列值为1987。如果我在birthyear>1990中添加一个复选框,并且我从不更新这个字段,但是我更新了这一行中的其他字段,会怎么样。我能更新此行吗?如果没有,那么有没有一种方法可以添加一个检查,这样我就可以在没有检查的情况下更新所有旧的行,但是新添加的行会受到影响,基本上只在insert查询上添加检查,而不在update查询上添加检查?希望我的问题清楚明白。

woobm2wo

woobm2wo1#

check约束会检查表中已有的值,如果有行违反该条件,则无法创建该约束。这就是约束的要点,Assert数据满足条件。
为了防止新数据违反条件,您可以创建一个触发器来检查它,如果违反了条件,就会抛出一个错误。大致如下:

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<>小提琴
但你真的应该再想想。扪心自问,你是否真的想让旧的数据违反条件。只清理旧的和有问题的数据可能比保留数据要好。否则,您永远无法确定行所满足的条件。

az31mfrm

az31mfrm2#

postgresql无法从新行中识别旧行,因此无法获得仅允许旧行冲突的约束。
正如在另一个答案中所解释的那样,如果创建约束,则会检查现有行的有效性。
有一个例外允许您创建 CHECK 包含违反条件的行的表上的约束:将约束创建为 NOT VALID . 则不会检查现有行的符合性。
但是,正如一开始所说的,只有在新行版本满足条件时才允许修改旧行。
另一个想法是增加一个新的专栏 old 类型 boolean 区分新旧行。然后可以显式地排除check条件中的旧行。

相关问题