146

我正进入(状态

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

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

4

7 回答 7

224

这通常是由 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';
于 2010-02-25T20:42:29.933 回答
47

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

于 2010-02-25T20:21:02.987 回答
6

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

1) 识别失败的语句

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

或者

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

并在发生时注意 UDUMP 中的 .trc 文件。

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

3.1) SQL 语句是 MERGE 吗?评估 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。有一些方法可以减少这种情况,例如正确设置 PCTFREE。使用 Note 122020.1 - Row Chaining and Migration 4.3) 如果表是另外索引组织的,请参阅:Note 102932.1 - Monitoring Chained Rows on IOTs

于 2016-04-01T21:44:32.777 回答
6

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

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

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

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

于 2019-02-14T13:56:43.477 回答
5

今天在 12c 上出现错误并且现有答案都不适合(没有重复,WHERE 子句中没有非确定性表达式)。根据 Oracle 的消息文本(以下重点),我的案例与错误的其他可能原因有关:

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

合并是更大批次的一部分,并在具有许多并发用户的实时数据库上执行。没有必要更改声明。我只是在合并之前提交了事务,然后单独运行合并,然后再次提交。所以在消息的建议操作中找到了解决方案:

行动:删除任何非确定性 where 子句并重新发布 dml

于 2016-06-21T10:41:21.083 回答
2
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),此错误发生在我身上

尝试了独特的方法

但是当我再次尝试合并时没有唯一的相同问题发生第二次是由于提交

合并后如果未完成提交,将显示相同的错误。

如果没有唯一性,如果在每次合并操作后给出提交,查询将起作用。

于 2018-07-26T02:38:49.627 回答
1

几个小时后我无法解决这个问题。最终,我只是做了一个选择,将两个表连接起来,创建了一个提取并为表中的 500 行创建了单独的 SQL 更新语句。丑陋但胜过花费数小时试图让查询工作。

于 2020-11-09T23:54:50.567 回答