gpt4 book ai didi

postgresql - postgresql 中的外键可能会被触发器破坏

转载 作者:行者123 更新时间:2023-11-29 11:09:36 25 4
gpt4 key购买 nike

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

这是正常行为吗?如果是这样,是否有办法获得我想要的行为(不可能有违规行为)?

编辑:

我最初创建外键作为 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:

约束违反可能是由错误的触发器引起的,见下文

最佳答案

我试图创建一个简单的示例来显示强制执行的外键约束。通过这个例子,我证明我不允许输入违反 fk 的数据,并且我证明如果在插入期间 fk 不在位,并且我启用了 fk,fk 约束会抛出一个错误,告诉我数据违反了 fk。所以我没有看到表中的数据如何违反现有的 fk。我在 9.0 上,但这在 8.3 上应该没有什么不同。如果您可以展示一个工作示例来证明您的问题可能会有所帮助。

--CREATE TABLES--
CREATE TABLE parent
(
parent_id integer NOT NULL,
first_name character varying(50) NOT NULL,
CONSTRAINT pk_parent PRIMARY KEY (parent_id)
)
WITH (
OIDS=FALSE
);
ALTER TABLE parent OWNER TO postgres;

CREATE TABLE child
(
child_id integer NOT NULL,
parent_id integer NOT NULL,
first_name character varying(50) NOT NULL,
CONSTRAINT pk_child PRIMARY KEY (child_id),
CONSTRAINT fk1_child FOREIGN KEY (parent_id)
REFERENCES parent (parent_id) MATCH SIMPLE
ON UPDATE CASCADE ON DELETE CASCADE
)
WITH (
OIDS=FALSE
);
ALTER TABLE child OWNER TO postgres;
--CREATE TABLES--

--INSERT TEST DATA--
INSERT INTO parent(parent_id,first_name)
SELECT 1,'Daddy'
UNION
SELECT 2,'Mommy';

INSERT INTO child(child_id,parent_id,first_name)
SELECT 1,1,'Billy'
UNION
SELECT 2,1,'Jenny'
UNION
SELECT 3,1,'Kimmy'
UNION
SELECT 4,2,'Billy'
UNION
SELECT 5,2,'Jenny'
UNION
SELECT 6,2,'Kimmy';
--INSERT TEST DATA--

--SHOW THE DATA WE HAVE--
select parent.first_name,
child.first_name
from parent
inner join child
on child.parent_id = parent.parent_id
order by parent.first_name, child.first_name asc;
--SHOW THE DATA WE HAVE--

--DELETE PARENT WHO HAS CHILDREN--
BEGIN TRANSACTION;
delete from parent
where parent_id = 1;

--Check to see if any children that were linked to Daddy are still there?
--None there so the cascade delete worked.
select parent.first_name,
child.first_name
from parent
right outer join child
on child.parent_id = parent.parent_id
order by parent.first_name, child.first_name asc;
ROLLBACK TRANSACTION;


--TRY ALLOW NO REFERENTIAL DATA IN--
BEGIN TRANSACTION;

--Get rid of fk constraint so we can insert red headed step child
ALTER TABLE child DROP CONSTRAINT fk1_child;

INSERT INTO child(child_id,parent_id,first_name)
SELECT 7,99999,'Red Headed Step Child';

select parent.first_name,
child.first_name
from parent
right outer join child
on child.parent_id = parent.parent_id
order by parent.first_name, child.first_name asc;

--Will throw FK check violation because parent 99999 doesn't exist in parent table
ALTER TABLE child
ADD CONSTRAINT fk1_child FOREIGN KEY (parent_id)
REFERENCES parent (parent_id) MATCH SIMPLE
ON UPDATE CASCADE ON DELETE CASCADE;

ROLLBACK TRANSACTION;
--TRY ALLOW NO REFERENTIAL DATA IN--

--DROP TABLE parent;
--DROP TABLE child;

关于postgresql - postgresql 中的外键可能会被触发器破坏,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3961825/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com