使用查询的返回值作为B表的外键,无需启动新的Transaction或删除外键约束

问题描述 投票:0回答:3

我正在表 A 中插入一个值,该值以序列类型作为主键。

使用查询的返回值作为表B的外键我得到:

错误:表“tb_midia_pessoa”的插入或更新违反了外键约束“tb_midia_pessoa_id_pessoa_fkey” 详细信息:表“tb_pessoa”中不存在键 (id_pessoa)=(30)

如何在不启动新事务或删除外键约束的情况下使用查询的返回值作为表 B 的外键?

postgresql transactions foreign-keys
3个回答
22
投票

您可以创建一个可延迟的 FK,只需使用 DEFERRABLE 或 INITIALLY DEFERRED,这取决于您。

http://www.postgresql.org/docs/current/static/sql-createtable.html


7
投票

下面的语句允许将不可推迟的约束推迟到事务提交为止。如果您不想更改 FK 定义。

SET CONSTRAINTS ALL DEFERRED;

0
投票

问题中描述的场景不应再引发错误!

这篇文章和已接受的答案不幸地将我引向了错误的道路,这花费了我几个小时的研究 - 希望我可以为你们中的一些人防止这种情况。

至少在 PostgreSQL v14 中,可以将记录插入到表

a
中,并使用其 id 作为表
b
中的引用。如果您至少使用 v14 并看到所描述的错误,则说明有其他问题,这对您来说是事务与外键。

以下示例运行没有错误,这证明问题中的问题不存在(不再) - 至少在问题中描述的简单场景中不存在:

create table tab_a (
  id int primary key generated always as identity,
  foo text
);

create table tab_b (
  id int primary key generated always as identity,
  a_id int NOT NULL references tab_a ON DELETE CASCADE,
  bar text
);

begin;
insert into tab_a (foo) values ('test') returning *;
insert into tab_b (a_id, bar) values (1, 'test') returning *;
commit;

我带着一些代码来到这里,尝试在不同的数据库连接上执行第二个插入语句 - 这显然无法访问事务所在连接上插入的数据。如果您来到这里,请彻底检查一下您的问题是否真的只与问题中给出的内容相关。

© www.soinside.com 2019 - 2024. All rights reserved.