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) ,它也有数据。

为什么会出现这种错误,如何解决?

540708 次浏览

您可能正在尝试多次更新目标表的同一行。我刚刚在我开发的 merge 语句中遇到了同样的问题。确保在合并的执行过程中,更新不会多次触及同一条记录。

这通常是由 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';

如何排除 ORA-30926错误? (文件编号471956.1)

1)识别失败的陈述

更改会话集事件“30926跟踪名称错误堆栈级别3”;

或者

更改系统设置事件“30926跟踪名称错误堆栈关闭”;

并在发生这种情况时注意 UDUMP 中的.trc 文件。

2)找到 SQL 语句后,检查它是否正确(可能使用解释计划或 tkprof 检查查询执行计划) ,如果最近没有这样做,则分析或计算相关表的统计数据。重新构建(或删除/重新创建)索引也可能有所帮助。

3.1) SQL 语句是 MERGE 吗? 计算 USING 子句返回的数据,以确保联接中没有重复的值。修改 merge 语句以包含确定性 where 子句

3.2)这是一个通过视图更新的声明吗? 如果是这样,请尝试将视图结果填充到表中,并尝试直接更新表。

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

3.4)该语句是否包含“ IN-Subquery”中的不可合并视图?如果查询具有“ FORUPDATE”子句,则可能会返回重复的行。见 Bug 2681037

3.5)表中是否有未使用的列? 删除这些列可以防止错误。

4)如果修改 SQL 不能修复错误,问题可能出在表上,特别是如果存在链式行。 4.1)对 SQL 中使用的所有表运行‘ AnalyzE TABLE VALIDATE strucCTURE CASCADE’语句,查看表或其索引中是否有任何损坏。 4.2)检查并消除表上任何 CHAINED 或迁移的 ROWS。有一些方法可以减少这种情况,比如正确设置 PCTFREE。 使用说明122020.1-行链接和迁移 4.3)如附表为“索引组织”,请参阅: 注102932.1-监视物联网上的链状行

今天在12c 上出现了错误,现有的答案都不符合(WHERE 子句中没有重复,没有不确定的表达式)。根据甲骨文的消息文本(强调如下) ,我的案例与该错误的另一个可能原因有关:

ORA-30926: 无法在源表中获得一组稳定的行
原因: 无法获得稳定的行集 因为大的 dml 活动或不确定的 where 子句。

合并是一个较大批处理的一部分,并且是在有许多并发用户的实时数据库上执行的。没有必要改变声明。我只是在合并之前提交了事务,然后分别运行合并,然后再次提交。因此,解决办法就在信息的建议行动中找到了:

动作: 删除任何不确定的地方分句和 重新发布 dml

SQL Error: ORA-30926: unable to get a stable set of rows in the source tables
30926. 00000 -  "unable to get a stable set of rows in the source tables"
*Cause:    A stable set of rows could not be got because of large dml
activity or a non-deterministic where clause.
*Action:   Remove any non-deterministic where clauses and reissue the dml.

这个错误发生在我的 因为重复的记录(16K)

独一无二的尝试成功了

但是当我尝试没有独特的合并时,同样的问题发生了 第二次是因为犯罪

在合并后,如果提交没有做相同的错误将显示。

如果没有惟一性,则如果在每次合并操作之后提交,则查询将工作。

关于在一般情况下使用 DISTINCT 解决 ORA-30926错误的进一步说明:

您需要确保 USING ()子句指定的数据集不会重复 连接柱的值,即 ON ()子句中的列

在 OP 的示例中,USING 子句只选择一个键,将 DISTINCT 添加到 USING 子句就足够了。但是,在一般情况下,USING 子句可以选择要匹配的键列和要在 UPDATE... SET 子句中使用的属性列的组合。因此,在一般情况下,将 DISTINCT 添加到 USING 子句仍然允许对相同的键执行不同的更新行,在这种情况下仍然会得到 ORA-30926错误。

这是对 dCookie 的回答和 Tagar 回答中的3.1点的详细阐述,根据我的经验,这可能不会立即显而易见。

几个小时后我还是没能解决这个问题。最后,我只是选择了连接的两个表,创建了一个提取,并为表中的500行创建了单独的 SQL 更新语句。虽然很难看,但总比花几个小时去查询要好。