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

时间:2010-02-25 20:14:00

标签: oracle sql-merge

我正在

  

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

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

7 个答案:

答案 0 :(得分:175)

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

答案 1 :(得分:38)

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

答案 2 :(得分:5)

  

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

1)识别失败的陈述

  

alter session set events'30926 trace name errorstack level 3';

  

alter system set events'30926 trace name errorstack off';

并在UDUMP发生时监视.trc文件。

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

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

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

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

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

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

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

答案 3 :(得分:3)

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

  

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

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

  

操作:删除所有非确定性where子句并重新发出dml

答案 4 :(得分:1)

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)

尝试了独特的方法

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

如果没有完成提交,合并后将显示错误。

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

答案 5 :(得分:0)

几个小时后我无法解决此问题。最终,我只是对两个表进行了选择,创建了一个数据提取,并为表中的500行创建了单独的SQL更新语句。丑陋,但要花费大量时间才能使查询正常工作。

答案 6 :(得分:-1)

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

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

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

这是DCookie的答案和Tagar答案中的要点3.1的阐述,根据我的经验,这可能不是立即显而易见的。