안녕하세요.
아래의 MYSQL쿼리를 ORACLE로 변환하여 시도중에 문의를 드려봅니다...ㅜㅜ
도저히 답을 못찾겠습니다.
MYSQL)
UPDATE
nodes src
JOIN paths paths ON paths.FromNodeID = src.NodeID
JOIN nodes dest ON dest.NodeID = Paths.ToNodeID
SET dest.Cost = CASE
WHEN dest.Cost IS NULL THEN src.Cost + Paths.Cost
WHEN src.Cost + Paths.Cost < dest.Cost THEN src.Cost + Paths.Cost
ELSE dest.Cost
END,
dest.PathID = Paths.PathID
WHERE src.NodeID = 1
AND (dest.Cost IS NULL OR src.Cost + Paths.Cost < dest.Cost)
AND dest.Calculated = 0;
--> MSQL에서 위와 같이 실행시 3개의 ROW가 갱신됩니다.(첨부 : 테이블3 결과)
위 SQL을 ORACLE 버전으로 수정해 보았습니다.
수정1)
UPDATE
(
SELECT dest.Cost dcost, src.Cost scost, Paths.Cost pcost, dest.PathID dpath, Paths.PathID ppath,
src.NodeID snode, dest.Calculated dcal
from nodes src,
(select * from paths) paths,
(select * from nodes) dest
where paths.FromNodeID = src.NodeID
and dest.NodeID = Paths.ToNodeID
)
SET dcost = CASE
WHEN dcost IS NULL THEN scost + pcost
WHEN scost + pcost < dcost THEN scost + pcost
ELSE dcost
END,
dpath = ppath
WHERE snode = 1
AND (dcost IS NULL OR scost + pcost < dcost)
AND dcal = 0
;
오류내역 : ORA-01779 키-보존된 것이 아닌 테이블로 대응한 열을 수정하였습니다.
오라클 12C버전으로 아래와 같이 2차로 수정하였습니다.
수정2)
merge into nodes a
using
(
SELECT dest.Cost dcost, src.Cost scost, Paths.Cost pcost, dest.PathID dpath, Paths.PathID ppath,
src.NodeID snode, dest.Calculated dcal
from nodes src,
(select * from paths) paths,
(select * from nodes) dest
where paths.FromNodeID = src.NodeID
and dest.NodeID = Paths.ToNodeID
) on (snode = 1
and (dcost IS NULL OR scost + pcost < dcost)
and dcal = 0
)
WHEN MATCHED THEN
UPDATE SET cost = CASE
WHEN dcost IS NULL THEN nvl(scost, 0) + nvl(pcost, 0)
WHEN nvl(scost, 0) + nvl(pcost, 0) < nvl(dcost, 0) THEN nvl(scost, 0) + nvl(pcost, 0)
ELSE nvl(dcost, 0)
END,
pathid = ppath
;
오류 : ORA-30926 원본 테이블의 고정행 집합을 가져올수 없습니다.
찾아보니 UPDATE할려고 하는 ROW가 1개 이상이여서 그런듯합니다.
아래의 테이블 내역으로 해당결과를 출력하고 싶습니다.
방법이 없을지 문의드립니다.
1. 테이블1과 테이블 2를 사용하여 3번의 결과도출
감사드립니다.
MERGE INTO nodes a USING (SELECT c.pathid , c.tonodeid , NVL(b.cost, 0) + c.cost cost FROM nodes b INNER JOIN paths c ON c.fromnodeid = b.nodeid WHERE b.nodeid = 1 ) d ON (a.nodeid = d.tonodeid) WHEN MATCHED THEN UPDATE SET a.cost = d.cost , a.pathid = d.pathid WHERE (a.cost IS NULL OR a.cost > b.cost) AND a.calculated = 0 ;