提问人:kaqqao 提问时间:11/17/2023 最后编辑:kaqqao 更新时间:11/17/2023 访问量:61
有没有办法知道在MERGE中执行了什么操作?
Is there a way to know what operation was performed in MERGE?
问:
使用 jOOQ 和 PostgreSQL,有没有办法知道为 MERGE、INSERT 或 UPDATE 执行了什么操作?
例如,使用 jOOQ 文档中的示例:
create.mergeInto(AUTHOR)
.using(create.selectOne())
// Suppose the last name is unique (natural key) in my case
.on(AUTHOR.LAST_NAME.eq("Hitchcock"))
.whenMatchedThenUpdate()
.set(AUTHOR.FIRST_NAME, "John")
.whenNotMatchedThenInsert(AUTHOR.LAST_NAME)
.values("Hitchcock")
.execute();
理想情况下,如果可能的话,我会同时获得生成的行和执行的操作。
注意:不是这个问题的重复。这是特定于 SQL Server 的。我的是特定于 PostgreSQL 和 jOOQ 的。
答:
PostgreSQL MERGE
不能将子句用于其基础 AND 语句,因此您只剩下受影响的行总数,而没有任何迹象表明它们是如何受到影响的。医生:RETURNING
INSERT
UPDATE
成功完成后,命令将返回表单的命令标记
MERGE
MERGE total_count
是更改的总行数(无论是插入、更新还是删除)。
total_count
没有带有 的子句。的 操作 ,不能包含 或 子句。
RETURNING
MERGE
INSERT
UPDATE
DELETE
RETURNING
WITH
您可以使用较旧的更新插入语法 INSERT...ON CONFLICT DO UPDATE
能够使用子句,并在其中检查受影响行的 xmax
系统列:插入的行将始终为零,更新的行将具有非零。示例。RETURNING
jOOQ 同时提供 .onConflict
() 和 .returningResult()(在 3.11 之前只是 .returning()
)。有问题的部分似乎是隐藏系统列的暴露,您可能无法立即引用。如果情况仍然如此,您将需要一个普通的 SQL
字段
(在此处找到)。
如果到达太麻烦了,并且您不介意乱扔您的架构,则可以设置一个反射器列,而不是尝试使用隐藏的 .或者,如果您确定插入批处理从不包含冲突解决值,请计算最终使用这些值的值。xmax
xmax
您始终可以这样做:
create.mergeInto(AUTHOR)
.using(create.selectOne())
// Suppose the last name is unique (natural key) in my case
.on(AUTHOR.LAST_NAME.eq("Hitchcock"))
.whenMatchedThenUpdate()
.set(AUTHOR.FIRST_NAME, "John")
.set(AUTHOR.LAST_ACTION, "UPDATE")
.whenNotMatchedThenInsert(AUTHOR.LAST_NAME, AUTHOR.LAST_ACTION)
.values("Hitchcock", "INSERT")
.execute();
然后再次读取记录,因为 PostgreSQL 不支持标准 SQL 语法或等效语法。MERGE
<data change delta table>
您还可以在触发器中自动执行上述操作。这样的触发器还可以使用 NOTIFY
命令向客户端指示它对每一行执行的操作,而不是存储在表中。LAST_ACTION
评论
LAST_ACTION
MERGED
MERGE
SELECT
INSERT...ON CONFLICT
trigger
table
trigger
notify
listen
notify
评论