批量插入数据计算新插入

时间:2017-01-16 21:31:57

标签: sql postgresql

假设我有一个带有列的复合pk的简单模式。 e.g

pk1:string

pk2:int

日期:时间戳

我正在从其他地方读取大约50个批次的数据,并希望存储它。我从中拉出的数据源是一个滑动窗口,所以我将从我已经插入的数据源接收数据,所以我不能盲目插入,否则我得到pk约束违规。

我想以合理的方式将新项目作为批处理插入,但也知道我为实际记录目的实际插入了多少新项目。

1 个答案:

答案 0 :(得分:1)

执行插入

对于postgresql版本9.5+,可以使用以下内容:

insert ... on conflict do nothing

示例:

INSERT INTO users (id, user_name, email) 
VALUES (1, 'hal', 'hal@hal.hal') 
ON CONFLICT DO NOTHING

对于最近的早期版本(自9+以来,我认为),可以从原始值和&amp ;;创建CTE。然后从那里插入:

WITH batch (id, user_name, email) AS (
VALUES
  (1, 'hal', 'hal@hal.hal'),
  (2, 'sal', 'sal@sal.sal')
)
INSERT INTO users (id, user_name, email) (
SELECT id, user_name, email
FROM batch
WHERE batch.id NOT IN (SELECT id FROM users)
)

或者,不是使用CTE,而是在处理每个批处理后截断的临时表中暂存值。

另请注意,如果使用CTE方法,可能需要显式地将字符串转换为适当的数据类型。

第三种选择是使用存储过程实现这一点。触发。这比其他两个更复杂,但可以使用早期版本的postgresql。

<强>登录

这两种方法都应报告插入的行数,但日志记录必须由数据库客户端执行。

e.g。在Python中,库psycopg2用于与postgresql交互,而psycopg2游标对象具有属性rowcount。我敢肯定,其他语言/框架编写的其他设计良好的库将以某种方式实现相同的功能。记录插入的行数必须从与数据库交互的程序部分完成。

但是,如果在同一个数据库中需要插入多少行的日志,那么upsert&amp;可以通过单个触发器+存储过程执行日志记录。

最后,由于这是upsert的一个特例,通过在堆栈溢出或其他站点上搜索postgresql upsert可以找到更多信息。我从postgresql wiki中发现了以下内容:

https://wiki.postgresql.org/wiki/UPSERT#PostgreSQL_.28today.29