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

ycl3bljg  于 2023-02-03  发布在  Oracle
关注(0)|答案(8)|浏览(1395)

我越来越
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),它也有数据。
为什么会出现这种错误,如何解决?

rqenqsqc

rqenqsqc1#

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

jtjikinw2#

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

iswrvxsc

iswrvxsc3#

对使用DISTINCT在一般情况下解决错误ORA-30926的进一步说明:
您需要确保USING()子句指定的数据集没有连接列(即ON()子句中的)的重复值。
在OP的示例中,USING子句仅选择一个键,只需将DISTINCT添加到USING子句中即可。但是,在一般情况下,USING子句可能选择要匹配的键列和要在UPDATE... SET子句中使用的属性列的组合。因此,在一般情况下,将DISTINCT添加到USING子句中仍将允许相同键的不同更新行。在这种情况下,您仍然会收到ORA-30926错误。
这是对DCookie的回答和Tagar的回答中的第3.1点的阐述,根据我的经验,这可能不是立即显而易见的。

1l5u6lss

1l5u6lss4#

如何解决ORA-30926错误?(文档ID 471956.1)
1)识别失败的语句
更改会话集事件“30926跟踪名称错误堆栈级别3”;

更改系统设置事件“30926跟踪名称错误堆栈关闭”;
并在发生时在UDUMP中查看.trc文件。
2)找到SQL语句后,检查它是否正确(可能使用解释计划或tkprof检查查询执行计划),如果最近没有这样做,则分析或计算有关表的统计信息。重建(或删除/重新创建)索引也可能有所帮助。
3.1)SQL语句是否为MERGE语句?请评估USING子句返回的数据,以确保联接中没有重复值。请修改merge语句以包括确定性where子句
3.2)这是通过视图的UPDATE语句吗?如果是,请尝试将视图结果填充到表中,然后尝试直接更新该表。
3.3)表上是否有触发器?请尝试禁用它以查看它是否仍然失败。
3.4)语句是否在“IN子查询”中包含不可合并的视图?如果查询包含“FOR UPDATE”子句,则这可能导致返回重复的行。请参见错误2681037
3.5)表中是否有未使用的列?删除这些列可以防止错误。
4)如果修改SQL不能纠正错误,则问题可能出在表上,尤其是存在链接行的情况下。4.1)对SQL中使用的所有表运行“ANALYZE TABLE VALIDATE STRUCTURE CASCADE”语句,以查看表或其索引中是否存在任何损坏。4.2)检查并消除表上的任何链接行或迁移行。有一些方法可以最大限度地减少这种情况。例如PCTFREE的正确设置。使用注解122020.1 -行链接和迁移4.3)如果表还按索引组织,请参见:注解102932.1 -监测IOT上的链接行

m3eecexj

m3eecexj5#

我今天在12c上遇到了这个错误,但没有一个现有的答案适合我(没有重复的答案,WHERE子句中没有不确定的表达式)。根据Oracle的消息文本(着重号在下面),我的案例与另一个可能的错误原因有关:
ORA-30926:无法在源表中获取稳定的行集
原因:无法获取稳定的行集**,原因是大型dml活动或不确定的where子句。
合并是较大批处理的一部分,并且是在具有许多并发用户的活动数据库上执行的。不需要更改语句。我只是在合并之前提交事务,然后单独运行合并,然后再次提交。因此,在消息的建议操作中找到了解决方案:
操作:删除任何不确定的where子句并
重新发出dml**。

zpf6vheq

zpf6vheq6#

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)
尝试与独特的,它的工作
但再次当我尝试合并没有唯一相同的proble发生第二次它是由于提交

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

如果没有unique,则如果在每个合并操作后都给出commit,Query将工作。

bttbmeg0

bttbmeg07#

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

lc8prwob

lc8prwob8#

正如前面有人解释的那样,可能您的MERGE语句试图多次更新同一行,但这不起作用(可能导致歧义)。
下面是一个简单的例子. MERGE,它尝试在匹配给定的搜索模式时将一些产品标记为找到:

CREATE TABLE patterns(search_pattern VARCHAR2(20));
INSERT INTO patterns(search_pattern) VALUES('Basic%');
INSERT INTO patterns(search_pattern) VALUES('%thing');

CREATE TABLE products (id NUMBER,name VARCHAR2(20),found NUMBER);
INSERT INTO products(id,name,found) VALUES(1,'Basic instinct',0);
INSERT INTO products(id,name,found) VALUES(2,'Basic thing',0);
INSERT INTO products(id,name,found) VALUES(3,'Super thing',0);
INSERT INTO products(id,name,found) VALUES(4,'Hyper instinct',0);

MERGE INTO products p USING
(
   SELECT search_pattern FROM patterns
) o
ON (p.name LIKE o.search_pattern)
WHEN MATCHED THEN UPDATE SET p.found=1;

SELECT * FROM products;

如果patterns表包含Basic%Super%模式,则MERGE将起作用,并将更新前三个产品但是如果patterns表包含Basic%%thing搜索模式,然后合并不起作用,因为它将尝试更新第二个产品两次,这导致了问题。如果某些记录应该更新多次,合并就不起作用。也许你会问为什么不更新两次!?
这里第一次更新1和第二次更新1是相同的值,但只是偶然的。现在看看这个场景:

CREATE TABLE patterns(code CHAR(1),search_pattern VARCHAR2(20));
INSERT INTO patterns(code,search_pattern) VALUES('B','Basic%');
INSERT INTO patterns(code,search_pattern) VALUES('T','%thing');

CREATE TABLE products (id NUMBER,name VARCHAR2(20),found CHAR(1));
INSERT INTO products(id,name,found) VALUES(1,'Basic instinct',NULL);
INSERT INTO products(id,name,found) VALUES(2,'Basic thing',NULL);
INSERT INTO products(id,name,found) VALUES(3,'Super thing',NULL);
INSERT INTO products(id,name,found) VALUES(4,'Hyper instinct',NULL);

MERGE INTO products p USING
(
   SELECT code,search_pattern FROM patterns
) s
ON (p.name LIKE s.search_pattern)
WHEN MATCHED THEN UPDATE SET p.found=s.code;

SELECT * FROM products;

现在第一个产品名称匹配Basic%模式,它将用代码B更新,但第二个产品匹配两个模式,不能同时用代码BT更新(不明确)!这就是为什么DB引擎抱怨。不要责怪它!它知道它在做什么!-)

相关问题