Gar*_*ord 5 sql postgresql exception upsert duplicates
我正在运行一个python脚本,将大量数据插入到Postgres数据库中,我使用单个查询来执行多行插入:
INSERT INTO table (col1,col2) VALUES ('v1','v2'),('v3','v4') ... etc
Run Code Online (Sandbox Code Playgroud)
我想知道如果它碰到插入的重复键会发生什么.它会停止整个查询并抛出异常吗?或者它只是忽略该特定行的插入并继续前进?
Erw*_*ter 10
该INSERT会只是插入所有行没什么特别不会发生,除非你有某种约束条件不允许重复/重叠值(PRIMARY KEY,UNIQUE,CHECK或EXCLUDE约束) -你没有在你的问题提了.但这就是你可能担心的事情.
假设有一个UNIQUE或PK约束(col1,col2),你正在处理一个教科书UPSERT情况.许多相关的问题和答案可以在这里找到.
通常,如果违反了任何约束,则会引发异常(除非陷入像plpgsql这样的过程服务器端语言),不仅会回滚语句,还会回滚整个事务.
即:没有其他事务会尝试同时写入同一个表.
使用WHERE NOT EXISTS ...或任何其他适用技术排除表中已有的行:
而且不要忘了删除重复内插入设置为好,这将不会被排除半反连接WHERE NOT EXISTS ...
一次处理这两种技术的一种方法是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;
Run Code Online (Sandbox Code Playgroud)
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 1
FROM tbl
WHERE col1 = t.c1 AND col2 = t.c2
);
Run Code Online (Sandbox Code Playgroud)
如果可以有很多欺骗,那么首先在源中折叠它们是值得的.否则使用一个子查询.
有关:
使用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!
Run Code Online (Sandbox Code Playgroud)
更详细的相关答案:
文档:
克雷格对UPSERT问题的参考答案:
| 归档时间: |
|
| 查看次数: |
5185 次 |
| 最近记录: |