具有延迟约束的违反sql的外键约束

blmhpbnm  于 2021-07-29  发布在  Java
关注(0)|答案(1)|浏览(358)

我试图将我的sql脚本设置到事务中,以实现数据库的原子性。
表格结构(简化):

CREATE TABLE foo (
    id serial  NOT NULL,
    foo varchar(50)  NOT NULL,    
    CONSTRAINT foo_pk PRIMARY KEY (id)
);

CREATE TABLE access (
    id serial  NOT NULL,
    foo_id int  NULL
    CONSTRAINT access_pk PRIMARY KEY (id)
);

ALTER TABLE access ADD CONSTRAINT access_foo
    FOREIGN KEY (foo_id)
    REFERENCES foo (id)
    ON DELETE  CASCADE 
    ON UPDATE  CASCADE 
    DEFERRABLE 
    INITIALLY DEFERRED;

在我的代码中,我首先声明: client.query('BEGIN'); (我使用的是npm库'pg')然后将一行插入表'foo',然后将另一个插入插入到'access',并使用第一个插入的foo\u id。在那之后是 client.query('COMMIT'); 所有这一切都是在一个尝试捕捉,在捕捉是 client.query('ROLLBACK'); 如果有任何一个插件出现问题,那么回滚似乎是有效的。当所有的事情都要完成的时候,我还是会因为这个而陷入困境:
消息:“在表“access”上插入或更新违反外键约束“access\u foo”
detail:“key(foo\u id)=(20)不在表“foo”中。”
我以为延迟约束就足够了,但我想我错了。欢迎任何帮助。

njthzxwz

njthzxwz1#

您可能对事务划分有一些问题。我做了一个简单的测试,效果很好。

insert into foo (id, foo) values (1, 'Anne');

start transaction;

insert into access (id, foo_id) values (101, 1);

insert into access (id, foo_id) values (107, 7); -- 7 does not exist yet...

insert into foo (id, foo) values (7, 'Ivan'); -- 7 now exists!

commit; -- at this point all is good

参见db fiddle的运行示例。

相关问题