使用postgres执行UPSERT语句时,例如
INSERT INTO tab1.summary(
table_name, target_field, check_n)
VALUES ('tab1', 'col1', 10),
('tab2', 'col2', 10)
ON CONFLICT(table_name, target_field, check_n)
DO UPDATE SET check_n = 20;
字符串
,作为数据输出不返回任何内容,但是,该消息显示“0”2,这意味着两行受到影响,没有任何错误。
但是,有没有办法将插入和更新的行数分别作为数据输出来检索呢?
2条答案
按热度按时间lokaqttq1#
您可以观察到系统列
xmax
:xmax
删除事务的标识(事务ID),对于未删除的行版本为零。在可见行版本中,此列可能为非零。这通常表示删除事务尚未提交,或者尝试的删除已回滚。你已经在所有的表中拥有了它,它已经被设置好了,你已经可以使用它了。通常,除非显式引用,它只是一个额外的隐藏字段,但是每个表的每一行都有它。
由upsert产生的结果将显示其
xmax
字段为0(插入)和非零(更新)。这是因为在幕后,update
实际上是insert
和delete
的组合:它插入一个新元组并删除旧元组,将其标记为过时,并准备在没有其他事务使用更改前的表快照时由vacuum
删除:demo字符串
您可以将其与使用手动添加的reflector column:demo2的方法进行比较
型
| 表名|目标场|检查_n|已更新|
| --|--|--|--|
| tab1| col1| 10 |F|
| tab2| col2| 10 |F|
型
| 已更新|XMAX|
| --|--|
| 不| 732 |
| F| 0 |
型
| 表名|目标场|检查_n|已更新|
| --|--|--|--|
| tab2| col2| 10 |F|
| tab1| col1| 20 |不|
| tab2| col2| 20 |F|
与使用粘贴的
was_updated
列相比,xmax
根本不必添加,因为它已经存在。envsm3lx2#
可以使用
returning
子句:demo字符串
| 插入计数|更新计数|
| --|--|
| 2 | 0 |
如果你再运行一次,强制冲突:
| 插入计数|更新计数|
| --|--|
| 0 | 2 |
当然,这个方法只在你的批处理不包含默认的
check_n=20
时才有效,在这种情况下,它会假设它是更新的,而不是插入的。型