[英]Postgres delete before insert in single transaction
PostgreSQL 数据库:v 9.4.24
create table my_a_b_data ... // with a_uuid, b_uuid, and c columns
注意:my_a_b_data 保留对 a 和 b 表的引用。 所以它保留了a和b的uuid。
其中: primary key (a_uuid, b_uuid)
还有一个索引:
create unique index my_a_b_data_pkey
on my_a_b_data (a_uuid, b_uuid);
在类似 Java jdbc 的代码中,在一个事务的范围内: (start() -> [code (delete, insert)] ->commit()])
( org.postgresql:postgresql:42.2.5 driver
)
delete from my_a_b_data where b_uuid = 'bbb';
insert into my_a_b_data (a_uuid, b_uuid, c) values ('aaa', 'bbb', null);
我发现插入失败了,因为删除还没有删除。 所以它失败了,因为它不能被复制。
问: DB 不能在一个事务中进行删除和插入是PostgreSQL中的某种限制吗,因为 PostgreSQL 在执行删除提交之前不会更新其索引,因此插入将失败,因为 id 或键(无论我们使用什么)已经存在于索引中?
可能的解决方案是什么? 分成两笔交易?
更新:订单完全相同。 当我在 SQL 控制台中单独测试 sql 时。 它工作正常。 我们使用 JDBI 库 v 5.29。
它看起来像这样:
@Transaction
@SqlUpdate("insert into my_a_b_data (...; // similar for the delete
public abstract void addB() ..
所以在代码中:
this.begin();
this.deleteByB(b_id);
this.addB(a_id, b_id);
this.commit();
我在插入重复值时遇到了类似的问题,我通过使用 Insert 和 Update 而不是 Delete 解决了这个问题。 我在 Python 上创建了这个过程,但你可以重现它:
首先,你创建一个临时表,就像你要插入值的目标表,不同的是这个表在提交后被删除。
CREATE TEMP TABLE temp_my_a_b_data (LIKE public.my_a_b_data INCLUDING DEFAULTS) ON COMMIT DROP;
我创建了一个 CSV(我必须将不同的数据合并到输入中),其中包含我想在我的表中输入/插入的值,并且我使用COPY函数将它们插入到 temp_table ( temp_my_a_b_data ) 中。
我在这篇与 Java 和 COPY PostgreSQL - \copy 命令相关的帖子中找到了这段代码:
String query ="COPY tmp from 'E://load.csv' delimiter ','";
使用 INSERT INTO 但使用ON_CONFLICT子句,您可以决定在由于指定约束而无法完成插入时执行操作,在下面的情况下我们进行更新:
INSERT INTO public.my_a_b_data SELECT * FROM temp_my_a_b_data ON CONFLICT (a_uuid, b_uuid,c) DO UPDATE SET a_uuid = EXCLUDED.a_uuid, b_uuid = EXCLUDED. c = EXCLUDED.c;`
注意事项:
我不确定,但您可以在不使用前面的步骤、临时表或从中复制的情况下执行第三步。 您可以只循环遍历这些值:
INSERT INTO public.my_a_b_data VALUES(value1, value2, null)
ON CONFLICT (a_uuid, b_uuid,c) DO UPDATE
SET a_uuid = EXCLUDED.a_uuid,
b_uuid = EXCLUDED.b_uuid, c = EXCLUDED.c;
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.