合并给出错误 ORA-30926: 无法在源表中获得一组稳定的行

Posted

技术标签:

【中文标题】合并给出错误 ORA-30926: 无法在源表中获得一组稳定的行【英文标题】:Merge into gives error ORA-30926: unable to get a stable set of rows in the source tables 【发布时间】:2017-09-04 09:42:02 【问题描述】:

我尝试按顺序运行接下来的 2 个查询。第一个完美运行,第二个抛出

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

我在网上搜索了一个解决方案,但我无法为我的查询复制它。谁能帮帮我?

查询 1:

merge into sdc_compare_person dcip
using (
select anumber, position, character
from sdc_diakrietposities_cip
where kind = 'Surname'
) x
on (dcip.sourcekey = x.anumber)
when matched then update set
dcip.GESVOR = substr(dcip.GESVOR, 1, x.position - 1) ||
                x.character ||
                substr(dcip.GESVOR, x.position + 1, length(dcip.GESVOR)-x.position)
;

188 rows merged.

查询 2:

merge into sdc_compare_person dcip
using (
select anumber, position, character
from sdc_diakrietposities_cip
where kind = 'Lastname'
) x
on (dcip.sourcekey = x.anumber)
when matched then update set
dcip.GESNAM_D = substr(dcip.GESNAM_D, 1, x.position - 1) ||
                x.character ||
                substr(dcip.GESNAM_D, x.position + 1, length(dcip.GESNAM_D) - x.position)
;

SQL Error: ORA-30926: Unable to get a stable set of rows in the source tables

【问题讨论】:

添加:此查询使用特殊字符更新列“dcip.gesnam_d”(来自列“x.character”)。所以 X 包含几个重复的 'anumber' 值,因为一些 'dcip_gesnam_d' 值可能有超过 1 个特殊字符。 可能与***.com/questions/2337271/…重复? 是的,这是正确的,但是根据给定的答案,我无法产生有效的解决方案。它不断抛出 ORA-30926 错误。查询 2 和查询 1 是同一个查询,我不明白为什么 2 有效而 1 无效。 在您的查询 2 中,使用子查询会产生两条具有相同数字的记录 一个查询有效,另一个无效。但是两个查询都有子查询产生两个或多个相同数量的记录。 【参考方案1】:

你总是可以使用普通更新,它不像 MERGE 那样优雅,但应该可以工作:

UPDATE sdc_compare_person dcip
SET dcip.GESNAM_D = (
    SELECT substr(dcip.GESNAM_D, 1, x.position - 1) ||
           x.character ||
           substr(dcip.GESNAM_D, x.position + 1, length(dcip.GESNAM_D) - 
                  x.position)
    FROM sdc_diakrietposities_cip x
    where kind = 'Lastname'
      AND dcip.sourcekey = x.anumber
)
WHERE dcip.sourcekey  IN (
   select anumber
   from sdc_diakrietposities_cip
   where kind = 'Lastname'
);

【讨论】:

【参考方案2】:

从 cmets 到问题,很明显作者想要多次更新同一条记录。 当然,当尝试通过合并构造来执行此操作时,这无法通过 ORA-30926。 在纯 oracle sql 中很难或不可能做到这一点,但使用 pl/sql 函数很容易做到。 例如:

create or replace function replace_chars(p_str varchar2, p_id number, p_kind varchar2) return varchar2 as
                                l_str varchar2(32767):=p_str;
begin
    for u in (select u.position, u.character  from sdc_diakrietposities_cip u 
                  where u.anumber=p_id and u.kind=p_kind order by u.position) loop
        if (u.position >= 1 or u.position <= length(l_str)) then
            l_str:=substr(l_str, 1, u.position-1)|| u.character || substr(l_str, u.position+1);
        end if;
    end loop;
    return l_str;
end;

这样使用:

update sdc_compare_person t 
set t.GESNAM_D= replace_chars(t.GESNAM_D, t.sourcekey, 'Lastname');

我建议在运行此之前备份您的表。

【讨论】:

Thanx @wolfrevokcats,这是我正在寻找的解决方案。尽管我的问题描述很糟糕......为此道歉。

以上是关于合并给出错误 ORA-30926: 无法在源表中获得一组稳定的行的主要内容,如果未能解决你的问题,请参考以下文章

无法在源表中获得一组稳定的行?

oracle 中报ora-30926 无法在源表中获得稳定的行 是怎么回事

oracle 中报ora-30926 无法在源表中获得稳定的行 是怎么回事

合并语句问题 - 错误无法在源表中获得一组稳定的行

Oracle PL/SQL 程序在源表中拆分逗号分隔的数据并推送到目标表中

SQL - 从源表中提取某些记录,但也交叉引用该表