我有两个表:
throw
我想编写一个查询或函数,该查询或函数将获取person_id的列表,并将它们映射到最终合并到的任何人(如果有)。如果有周期性合并,我也想抛出一个错误。
try/catch
我怎样才能做到这一点?使用CTE,CONNECT BY还是递归功能?
答案 0 :(得分:0)
这是一个搜索姓氏列表的功能
public class ConditionalOrderService{
public void doMapping(){
IConditionalOrder order = new ConditionalOrderDTO();
ModelMapper mapper= new ModelMapper();
mapper.map(order,OrderDestination.class);
}
}
这是一个调用列表的示例,该列表不会发生异常
CREATE OR REPLACE FUNCTION findTheLastPersonList(
pi_startPersonList sys.odcinumberlist
)
RETURN sys.odcinumberlist
AS
lv_lastPersonList sys.odcinumberlist := new sys.odcinumberlist();
/* Get the last merged person in a chain
*
* @param pi_startPersonId Person from which searching should be started
* @return Id of the last person in a chain or pi_startPersonId in case person is merged to nobody
*/
FUNCTION findTheLastPerson(
pi_startPersonId NUMBER
)
RETURN NUMBER
AS
lv_laslPersonId NUMBER;
BEGIN
BEGIN
WITH t1(person_id, person_merged_to_id, lvl) AS (
-- Anchor member.
SELECT person_id,
person_merged_to_id,
1 AS lvl
FROM person_merge
WHERE person_id = pi_startPersonId
UNION ALL
-- Recursive member.
SELECT t2.person_id,
t2.person_merged_to_id,
lvl+1
FROM person_merge t2, t1
WHERE t2.person_id = t1.person_merged_to_id
)
SELECT person_merged_to_id
INTO lv_laslPersonId
FROM (
SELECT person_id,
person_merged_to_id,
lvl,
max(lvl) OVER () AS max_lvl
FROM t1
) t
WHERE t.lvl = t.max_lvl;
EXCEPTION
WHEN NO_DATA_FOUND THEN
lv_laslPersonId := pi_startPersonId;
END;
RETURN lv_laslPersonId;
END findTheLastPerson;
BEGIN
FOR i IN 1..pi_startPersonList.Count LOOP
lv_lastPersonList.Extend();
lv_lastPersonList(i) := findTheLastPerson(pi_startPersonId => pi_startPersonList(i));
END LOOP;
RETURN lv_lastPersonList;
END findTheLastPersonList;
以及引发异常的情况下的通话示例
DECLARE
lv_toFind sys.odcinumberlist := sys.odcinumberlist(1, 2, 3, 4);
lv_result sys.odcinumberlist;
BEGIN
lv_result := findTheLastPersonList(
pi_startPersonList => lv_toFind
);
FOR i IN 1..lv_result.COUNT LOOP
dbms_output.put_line(lv_toFind(i) || ' => ' || lv_result(i));
END LOOP;
END;
/