我在postgres中创建了一些表,将一个外键从一个表添加到另一个表,并设置为DELETE以级联.奇怪的是,我有一些字段似乎违反了这个约束.

这是正常行为吗?如果是的话,有没有办法达到我想要的行为(不可能违反规定)?

编辑:

我最初创建外键作为CREATE TABLE的一部分,只是使用

... REFERENCES product (id) ON UPDATE CASCADE ON DELETE CASCADE

pgAdmin3给出的当前代码是

ALTER TABLE cultivar
  ADD CONSTRAINT cultivar_id_fkey FOREIGN KEY (id)
      REFERENCES product (id) MATCH SIMPLE
      ON UPDATE CASCADE ON DELETE CASCADE;

编辑2:

为了澄清这一点,我暗自怀疑,只有在更新/插入发生时才会判断约束,但之后就再也不会查看约束了.不幸的是,我对postgres了解不够,无法确定这是否属实,也无法确定在不运行这些判断的情况下,字段如何最终进入数据库.

如果是这种情况,有没有办法判断所有外键并解决这些问题?

编辑3:

错误的触发器可能会导致违反约束,请参见下文

推荐答案

到目前为止,我读到的所有内容似乎都表明,只有在插入数据时才会判断约束.(或在创建约束时)例如the manual on set constraints.

This makes sense and - if the database works properly - should be good enough. I'm still curious how I managed to circumvent this or if I just read the situation wrong and there was never a real constraint violation to begin with.

无论哪种情况,案件都已结案:-/

-------更新--------

肯定有违反约束的情况,是由错误的触发器引起的.下面是要复制的脚本:

-- Create master table
CREATE TABLE product
(
  id INT NOT NULL PRIMARY KEY
);

-- Create second table, referencing the first
CREATE TABLE example
(
  id int PRIMARY KEY REFERENCES product (id) ON DELETE CASCADE
);

-- Create a (broken) trigger function
--CREATE LANGUAGE plpgsql;
CREATE OR REPLACE FUNCTION delete_product()
  RETURNS trigger AS
$BODY$
    BEGIN
      DELETE FROM product WHERE product.id = OLD.id;
      -- This is an error!
      RETURN null;
    END;
$BODY$
  LANGUAGE plpgsql;

-- Add it to the second table
CREATE TRIGGER example_delete
  BEFORE DELETE
  ON example
  FOR EACH ROW
  EXECUTE PROCEDURE delete_product();

-- Now lets add a row
INSERT INTO product (id) VALUES (1);
INSERT INTO example (id) VALUES (1);

-- And now lets delete the row
DELETE FROM example WHERE id = 1;

/*
Now if everything is working, this should return two columns:
(pid,eid)=(1,1). However, it returns only the example id, so
(pid,eid)=(0,1). This means the foreign key constraint on the
example table is violated.
*/
SELECT product.id AS pid, example.id AS eid FROM product FULL JOIN example ON product.id = example.id;

Postgresql相关问答推荐

使用Spring data jpa和CriteriaQuery在jsonb列中搜索操作

如何在PostgreSQL中对深度嵌套的jsonb属性创建索引

Postgres将唯一索引添加到已在分区上具有PK的分区表中,然后添加PK

即使不对订阅服务器进行任何修改,Postgres逻辑复制也可能发生冲突吗?

Postgres:一次插入多行时自定义upsert(存储过程?)?

在 postgres/presto/AWS-Athena 中,与 array_agg( (col1, col2) ) 相反的是什么来获得每组多行?

Postgres 低估了导致错误查询计划的行数

Postgis 不只使用索引扫描

我可以使用 Rails 将数组存储在 hstore 中吗

PostgreSQL 中基于时间戳的移动平均线

如何更改几何列的 SRID?

Heroku PGError:operator does not exist: character varying = integer

无法向 postgresql 数据库授予用户权限(对于 rails 应用程序)

如何禁用 postgresql缓存优化?

使用 pg-promise 插入多条记录

在 postgres 中创建超级用户

Postgres:为 CAST 失败定义一个默认值?

如何在postgresql中编写关于最大行数的约束?

升级到 Yosemite 10.10 后无法连接到 postgresql 数据库

在 docker-compose up 后加载 Postgres 转储