gpt4 book ai didi

sql - 插入多行时重复项会发生什么情况?

转载 作者:行者123 更新时间:2023-11-29 11:26:37 28 4
gpt4 key购买 nike

我正在运行一个将大量数据插入 Postgres 数据库的 python 脚本,我使用单个查询来执行多行插入:

INSERT INTO table (col1,col2) VALUES ('v1','v2'),('v3','v4') ... etc

我想知道如果它为插入插入一个重复的键会发生什么。它会停止整个查询并抛出异常吗?或者它会忽略该特定行的插入并继续前进吗?

最佳答案

INSERT 将只插入所有行并且没有会发生特殊情况,除非您有某种constraint不允许重复/重叠值(PRIMARY KEYUNIQUECHECKEXCLUDE 约束)- 您没有提到在你的问题中。但这可能就是您担心的。

假设(col1,col2) 上有UNIQUE 或PK 约束,您正在处理教科书UPSERT 情况。可在此处找到许多相关问题和答案。

通常,如果违反了任何约束,就会引发异常(除非陷入子事务中,就像在 plpgsql 这样的过程服务器端语言中可能发生的那样)不仅会回滚语句,还会回滚整个交易

没有并发写入

即:没有其他事务会尝试同时写入同一个表。

同时处理两者的一种技术是EXCEPT:

INSERT INTO tbl (col1, col2)
VALUES
(text 'v1', text 'v2') -- explicit type cast may be needed in 1st row
, ('v3', 'v4')
, ('v3', 'v4') -- beware of dupes in source
EXCEPT SELECT col1, col2 FROM tbl;

EXCEPT没有关键字 ALL 折叠源中的重复行。如果您知道没有重复项,或者您不想默默地折叠重复项,请使用 EXCEPT ALL(或其他技术之一)。见:

一般来说,如果目标表WHERE NOT EXISTS 结合源上的DISTINCT 可能会更快:

INSERT INTO tbl (col1, col2)
SELECT *
FROM (
SELECT DISTINCT *
FROM (
VALUES
(text 'v1', text'v2')
, ('v3', 'v4')
, ('v3', 'v4') -- dupes in source
) t(c1, c2)
) t
WHERE NOT EXISTS (
SELECT FROM tbl
WHERE col1 = t.c1 AND col2 = t.c2
);

如果有很多重复项,首先将它们折叠到源代码中是值得的。否则少用一个子查询。

相关:

并发写入

使用 Postgres UPSERT 实现 INSERT ... ON CONFLICT ...Postgres 9.5 或更高版本中:

INSERT INTO tbl (col1,col2)
SELECT DISTINCT * -- still can't insert the same row more than once
FROM (
VALUES
(text 'v1', text 'v2')
, ('v3','v4')
, ('v3','v4') -- you still need to fold dupes in source!
) t(c1, c2)
ON CONFLICT DO NOTHING; -- ignores rows with *any* conflict!

进一步阅读:

文档:

Craig 对 UPSERT 问题的引用答案:

关于sql - 插入多行时重复项会发生什么情况?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30875185/

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