我想知道是否可以添加某种检查,以便在更新部分成功时中止数据修改 CTE。附件是代表问题的最小查询。如果Updated_rows尚未更新 WHERE IN 子句中指定的 3 行,我希望查询失败。
如果将此查询重写为交互式事务,则很容易实现这一点,但我想知道是否可以在将事物保留为单个数据修改 CTE 的同时实现此目的。
with updated_rows as (
update some_table
set status = 'SUCCEEDED'
where id in ('a', 'b', 'c') and status = 'PENDING'
returning *
), more_updated_rows as (
update another_table
set total = total + 3
where completed = false
returning *
) select * from more_updated_rows
仅当遇到错误时查询才会失败。您可以在外部查询中引发一个:
但这很尴尬,而且错误将毫无意义。更好的解决方案是在客户端获取结果计数,如果不符合预期,则回滚事务并报告错误。
第一个 CTE - 选择并计算将更新的行数。另外检查这些是不同的行(即要更新的所有 3 行包含不同的列值,而不是一个值的 3 个重复) - 当标记列唯一且不可为空时,可以将其删除。
第二个 CTE - 使用附加条件更新行,该条件检查要更新的行数。如果要更新的行数不是 3,则不会更新任何行。
外部查询返回整个操作状态附加检查的金额。它必须返回 (3,3,3) 或 (0,0,0)。
附言。查询不会生成任何错误 - 当表中并非值列表中的所有值都存在时,这种情况不是错误,而是正常的处理流程。如果这是逻辑错误,那么客户端必须生成相应的异常(我已经尝试过,金额不匹配,我惊慌)。