ORA-30926:无法在源表中获得稳定的一组行

我正进入(状态

ORA-30926:无法在源表中获得稳定的一组行

在以下查询中:

MERGE INTO table_1 a USING (SELECT a.ROWID row_id, 'Y' FROM table_1 a ,table_2 b ,table_3 c WHERE a.mbr = c.mbr AND b.head = c.head AND b.type_of_action <> '6') src ON ( a.ROWID = src.row_id ) WHEN MATCHED THEN UPDATE SET in_correct = 'Y'; 

我已经运行了table_1它有数据,而且我运行了也有数据的内部查询( src )。

为什么会出现这个错误,怎么解决?

这通常是由USING子句中指定的查询中的重复项造成的。 这可能意味着TABLE_A是父表,并且多次返回相同的ROWID。

你可以通过在查询中使用DISTINCT来快速解决问题(事实上,如果'Y'是一个常数值,你甚至不需要把它放在查询中)。

假设你的查询是正确的(不知道你的表),你可以做这样的事情:

  MERGE INTO table_1 a USING (SELECT distinct ta.ROWID row_id FROM table_1 a ,table_2 b ,table_3 c WHERE a.mbr = c.mbr AND b.head = c.head AND b.type_of_action <> '6') src ON ( a.ROWID = src.row_id ) WHEN MATCHED THEN UPDATE SET in_correct = 'Y'; 

您可能试图多次更新目标表的同一行。 我刚刚在我开发的合并声明中遇到了同样的问题。 确保您的更新在执行合并时不会多次触及相同的logging。

如果今天在12c上出现错误,并且没有现有的答案(在WHERE子句中没有重复,没有非确定性expression式)。 根据Oracle的消息文本,我的情况与错误的其他可能原因有关(重点如下):

ORA-30926:无法在源表中获得稳定的一组行
原因: 由于大型dml活动或非确定性where子句,无法获得稳定的行集。

合并是一个更大的批处理的一部分,并在与许多并发用户的实时数据库上执行。 没有必要改变陈述。 我只是在合并之前提交事务,然后分别运行合并,然后再次提交。 所以解决方法是在消息的build议操作中find的:

行动:删除任何非确定性的地方条款,并重新发布dml

如何解决ORA-30926错误? (Doc ID 471956.1)

1)确定失败的陈述

改变会话设置事件'30926跟踪名称errorstack级别3';

要么

修改系统设置事件“30926跟踪名称错误closures”;

并在UDUMP中观察.trc文件。

2)findSQL语句,检查是否正确(可能使用explain plan或tkprof检查查询执行计划),如果最近还没有完成,则分析或计算相关表的统计信息。 重build(或删除/重新创build)索引也可能有帮助。

3.1)SQL语句是否合并? 评估由USING子句返回的数据,以确保连接中没有重复的值。 修改合并语句以包含确定性的where子句

3.2)这是一个UPDATE语句通过一个视图? 如果是这样,请尝试将视图结果填充到表中,然后尝试直接更新表。

3.3)桌子上有触发器吗? 尝试禁用它,看看它是否仍然失败。

3.4)该语句是否在'IN-Subquery'中包含一个不可合并的视图? 如果查询具有“FOR UPDATE”子句,这可能会导致重复的行被返回。 参见错误2681037

3.5)桌子是否有未使用的列? 删除这些可能会防止错误。

4)如果修改SQL不能解决错误,问题可能与表,特别是如果有链接的行。 4.1)在SQL中使用的所有表上运行“ANALYZE TABLE VALIDATE STRUCTURE CASCADE”语句,以查看表或其索引是否有任何损坏。 4.2)检查并消除桌子上的任何CHAINED或迁移的ROWS。 有一些方法可以最大限度地减less这种情况,比如正确设置PCTFREE。 使用注释122020.1 – 行链接和移植4.3)如果表格是索引组织的,请参阅:注释102932.1 – 监视IOT上的链式行