我收到ORA-30926错误。我对此进行了研究,发现这通常是由USING
子句中指定的查询中的重复引起的。
问题是我最终删除了重复项并存储在一个临时表(temp_distinct
)中,而我在MERGE
中指的是这个表。这是我的代码片段:
MERGE INTO name_test nt
USING (select name from temp_distinct) s
ON (1=1)
WHEN MATCHED
THEN UPDATE SET nt.fn = s.name, nt.LN = s.name
这是我的表的结构:
NAME_TEST
:
FN LN
----- -----
Ruc Rag
Ruc Ran
Sam Kum
Ruc Ran
Ruc Kum
Ran Dev
Rag Agar
Rag Ran
TEMP_DISTINCT
:
FN NUMB NAME NUM
----- ---- ----- ---
Sam 1 Mark 1
Rag 2 Steve 2
Dev 3 John 3
Kum 4 Dave 4
Ruc 5 Mich 5
Agar 6 Dean 6
Ran 7 Phil 7
因此,您可以看到USING
子句中没有重复。我正在尝试替换NT.FN = S.NAME
和NT.LN = S.NAME
。
基本上我想用来自FN
表的LN
和NAME_TEST
中的名称替换TEMP_DISTINCT
表中不同的名称。最终输出应如下所示:
FN LN
------ ------
Mich Steve
Mich Phil
Mark Dave
Mich Phil
Mich Dave
Phil John
Steve Dean
Steve Ran
答案 0 :(得分:1)
您的查询无法执行,因为(1 = 1)
oracle无法获得一组稳定的行,要清楚检查一下:
SQL> create table ttt (name varchar2(20 char));
Table created.
SQL> insert into ttt values('first1');
1 row created.
SQL> insert into ttt values('second2');
1 row created.
SQL> merge into ttt t1 using (select 'name' name from dual) t2 on (1 = 1) when matched then update set t1.name = t2.name;
2 rows merged.
SQL> select * from ttt;
NAME
--------------------
name
name
“t2”子查询中只有一行,并且合并操作已成功完成。但是如果你的子查询得到多行,我会遇到ORA-30926:
SQL> merge into ttt t1 using (select 'name' || level name from dual connect by rownum < 4) t2 on (1 = 1) when matched then update set t1.name = t2.name;
merge into ttt t1 using (select 'name' || level name from dual connect by rownum < 4) t2 on (1 = 1) when matched then update set t1.name = t2.name
*
ERROR at line 1:
ORA-30926: unable to get a stable set of rows in the source tables
SQL> select * from ttt;
NAME
--------------------
name
name
SQL>
Oracle不知道哪些值与行相关联。您的结果集不明确。为了能够执行此合并,您必须具有正常条件,例如:
SQL> alter table ttt add id number(10);
Table altered.
SQL> update ttt set name = 'name1', id = rownum;
2 rows updated.
SQL> select * from ttt;
NAME ID
-------------------- ----------
name1 1
name1 2
SQL> merge into ttt t1 using (select 'name' name, level id from dual connect by rownum < 4) t2 on (t1.id = t2.id) when matched then update set t1.name = t2.name;
2 rows merged.
SQL> select * from ttt;
NAME ID
-------------------- ----------
name 1
name 2
SQL>
正如您所见,“ttt”表已成功合并。
答案 1 :(得分:1)
除了来自@zaratustra的解释之外,您的合并还尝试将fn
和ln
设置为相同的name
值,因此它不会给出结果你想要它甚至有效。在您尝试更新fn
条款时,您无法在ln
条款中使用using
或name_test
。
如果您的fn
表格中有一个主键(或至少是唯一的)列,那么您可以在合并中包含该列,但您仍然只能正确更新{{1}一次通过}或ln
值。
我不确定你为什么不进行简单的更新:
update name_test nt
set fn = (select td.name from temp_distinct td where td.fn = nt.fn),
ln = (select td.name from temp_distinct td where td.fn = nt.ln);
8 rows updated.
select * from name_test;
FN LN
----- -----
Mich Steve
Mich Phil
Mark Dave
Mich Phil
Mich Dave
Phil John
Steve Dean
Steve Phil