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


129

我正进入(状态

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

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

Answers:


202

这通常是由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
这可能就是为什么其他方法(对我来说)也为我返回其他错误的原因(例如“此处不允许使用过程,函数,包或类型”和“在尝试执行以下操作时无法修改映射到非键保留表错误的列”插入视图”)。〜如果对其他人有帮助,即使添加了distance in,直到重新排列内部查询的联接后,我仍然遇到相同的错误,因此我从返回多行并从那里进行内部联接的表开始...如果那样说得通。
jinglesthula 2012年

40

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


1
+1,谢谢,这只是在目标表上发生的重复次数很少(至少基于合并中使用的键)。
tbone

6

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

1)确定失败的陈述

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

要么

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

并在UDUMP中监视.trc文件。

2)找到SQL语句后,检查它是否正确(也许使用explain plan或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。使用说明122020.1-行链接和迁移4.3)如果该表还具有索引索引,请参阅:注102932.1-监视IOT上的链接行


5

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

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

合并是较大批处理的一部分,并且在具有许多并发用户的实时数据库中执行。无需更改该语句。我只是在合并之前提交了事务,然后分别运行合并,然后再次提交。因此,在消息的建议操作中找到了解决方案:

操作:删除所有不确定的where子句,然后重新发出dml


NETWORK_LINK在统计信息收集阶段,我收到通过网络(使用直接连接到源数据库的参数)进行DataPump导入的错误消息,而您突出显示的注释可能会对此进行解释。幸运的是,统计数据受到了影响。
Mark Stewart

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)

尝试了独特的方法

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

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

如果没有唯一性,则查询将在每个合并操作之后给出提交的情况下工作。


-1

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

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

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

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

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.