VALIDATE CONSTRAINT为什么找不到此外键冲突?

时间:2018-08-23 15:55:51

标签: postgresql

我认为我不了解VALIDATE CONSTRAINT应该做什么。我正在转换一个数据库,以用于即将推出的公司旗舰软件产品的重大升级。过去的开发人员很懒惰,没有理会应该在哪里指定外键。对于我们产品的新版本,将指定并强制使用适当的外键。

因此,我想将数据导入到我的新数据库中,然后确保没有外键冲突。在努力处理事务的开始和结束时间以及处理循环键并以惊人的速度无所事事之后,我决定只禁用所有表上的所有触发器(这将禁用PostgreSQL中的外键约束检查,因为它们在幕后使用了触发器),数据,重新启用触发器,然后发出VALIDATE CONSTRAINT命令。但是,在我的小测试脚本中,验证未能找到任何约束违例。为什么不呢?

这是测试脚本。我正在创建一个名为gas_types_minimum的表,并带有一个名为gas_type的列。我没有在该表中创建任何记录。然后,我创建一个名为base_types_minimum的表,其中包含一个名为base_type的列和一个名为gas_type的列。我禁用了它的触发器,因此即使没有gas_type记录,我也可以插入base_type记录。然后,插入气体类型为“ H2”的氢基类型。然后,我重新打开触发器并验证约束。我没有错。

DROP TABLE IF EXISTS base_types_minimum;
DROP TABLE IF EXISTS gas_types_minimum;
CREATE TABLE public.gas_types_minimum
(
    gas_type character varying(32) COLLATE pg_catalog."default",
    CONSTRAINT gas_type_minimum_pkey PRIMARY KEY (gas_type)
);

CREATE TABLE public.base_types_minimum
(
    base_type character varying(32) COLLATE pg_catalog."default" NOT NULL,
    gas_type character varying(32) COLLATE pg_catalog."default",
    CONSTRAINT base_type_minimum_pkey PRIMARY KEY (base_type),
    CONSTRAINT base_type_minimum_gas_type_minimum_fk FOREIGN KEY (gas_type)
        REFERENCES public.gas_types_minimum (gas_type) MATCH SIMPLE
        ON UPDATE NO ACTION
        ON DELETE NO ACTION
);

alter table base_types_minimum disable trigger all;
insert into base_types_minimum values ('Hydrogen', 'H2');
alter table base_types_minimum enable trigger all;

alter table base_types_minimum validate constraint base_type_minimum_gas_type_minimum_fk;

1 个答案:

答案 0 :(得分:1)

原因是外键约束已被标记为有效,因此未选中。

VALIDATE CONSTRAINT仅对被定义NOT VALID的约束有用,而您的约束则没有。以后没有支持的使约束无效的方法,因为它没有用。

通过禁用触发器,您实际上破坏了完整性,并且无法恢复。因此,如果您是超级用户(应该知道他们在做什么),则只能禁用实现外键的触发器。

最好的办法是删除损坏的外键约束。

有一个–不支持! –如何将约束标记为无效:

UPDATE pg_catalog.pg_constraint
SET convalidated = FALSE
WHERE conname = 'base_type_minimum_gas_type_minimum_fk';

您只能以超级用户身份执行此操作,我不建议这样做。只需删除该外键约束即可。