合并查询返回ORA-30926:无法在源表中获得稳定的行集

Ana*_*may 3 .net sql oracle

我有两个合并查询,一个接一个地触发

第一次查询

merge into MyTable
using
(   
select distinct nullLogSetId.Id as IdToUpdate,
       knownLogSetId.LogSetId LogSetIdToUpdateTo
from MyTable knownLogSetId 
join MyTable nullLogSetId
  on knownLogSetId.IdentifierType = nullLogSetId.IdentifierType
 and knownLogSetId.Identifier = nullLogSetId.Identifier 
where 

    knownLogSetId.IdentifierType = 'ABC'
    and knownLogSetId.LogSetId >= 0 
    and nullLogSetId.LogSetId = -1
)
on (Id = IdToUpdate)
when matched then
update set LogSetId = LogSetIdToUpdateTo
Run Code Online (Sandbox Code Playgroud)

第二查询

merge into MyTable
using
(

  select distinct nullLogSetId.Id as IdToUpdate,
                  knownLogSetId.LogSetId LogSetIdToUpdateTo
  from MyTable knownLogSetId 
  join MyTable nullLogSetId
    on knownLogSetId.IdentifierType = nullLogSetId.IdentifierType 
   and knownLogSetId.Identifier = nullLogSetId.Identifier 
  where 
    knownLogSetId.IdentifierType = 'DEF'
    and knownLogSetId.LogSetId >= 0 
    and nullLogSetId.LogSetId = -1
) on (Id = IdToUpdate)
when matched then
update set LogSetId = LogSetIdToUpdateTo
Run Code Online (Sandbox Code Playgroud)

我正在依次使用OracleCommand从.NET调用这些查询

第一个工作正常,但是当第二个被触发时,我得到了错误

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

如果您看到我在两个查询中都使用了distinct,那么我已经阅读了所有有关relevent的问题,并从我的角度进行了尝试,因此重复行不是问题。能否请任何人帮助我解决我做错的事情,这可能是基本问题,因为我是刚接触查询的人,请帮助我

Luk*_*zda 6

如果您看到我在两个查询中都使用了distinct,那么行的重复不是问题。

您可能有重复的数据。与其他列一起使用时DISTINCT,不能保证您具有IdToUpdate唯一性。看到:

CREATE TABLE #MyTable(IdToUpdate INT, LogSetIdToUpdateTo INT);

INSERT INTO #MyTable VALUES (1,1), (1,2), (2,1),(3,1);

SELECT DISTINCT IdToUpdate, LogSetIdToUpdateTo
FROM #MyTable;
Run Code Online (Sandbox Code Playgroud)

LiveDemo

你会得到IdToUpdate两次。检查您的数据:

with cte AS (
  select distinct nullLogSetId.Id as IdToUpdate,
                  knownLogSetId.LogSetId LogSetIdToUpdateTo
  from MyTable knownLogSetId 
  join MyTable nullLogSetId
    on knownLogSetId.IdentifierType = nullLogSetId.IdentifierType 
   and knownLogSetId.Identifier = nullLogSetId.Identifier 
  where 
    knownLogSetId.IdentifierType = 'DEF'
    and knownLogSetId.LogSetId >= 0 
    and nullLogSetId.LogSetId = -1
)
SELECT IdToUpdate, COUNT(*) AS c
FROM cte
GROUP BY IdToUpdate
HAVING COUNT(*) > 1;
Run Code Online (Sandbox Code Playgroud)

一种方法是使用聚合函数(MAX/MIN)而不是DISTINCT

merge into MyTable
using
(

  select nullLogSetId.Id as IdToUpdate,
         MAX(knownLogSetId.LogSetId) AS LogSetIdToUpdateTo 
  from MyTable knownLogSetId 
  join MyTable nullLogSetId
    on knownLogSetId.IdentifierType = nullLogSetId.IdentifierType 
   and knownLogSetId.Identifier = nullLogSetId.Identifier 
  where 
    knownLogSetId.IdentifierType = 'DEF'
    and knownLogSetId.LogSetId >= 0 
    and nullLogSetId.LogSetId = -1
  GROUP BY nullLogSetId.Id
) on (Id = IdToUpdate)
when matched then
update set LogSetId = LogSetIdToUpdateTo
Run Code Online (Sandbox Code Playgroud)