我需要从几个不同的表中收集很多id到某种变量中以传递给另一个函数。从中获取ID的表是动态的,具体取决于下面的参数。问题是,如果没有更好的方法可以做到这一点,因为这种方法必须多次复制和重新分配数组。将它全部插入临时表会更好吗?使用动态sql会更好吗?请参阅下面的get_ids函数:
FUNCTION concat (
iList1 IN ID_ARRAY,
iList2 IN ID_ARRAY
)
RETURN ID_ARRAY IS
lConcat ID_ARRAY;
BEGIN
SELECT column_value BULK COLLECT INTO lConcat FROM (
(SELECT column_value FROM TABLE(CAST( iList1 AS ID_ARRAY)))
UNION ALL
(SELECT column_value FROM TABLE(CAST( iList2 AS ID_ARRAY)))
);
RETURN lConcat;
END concat;
FUNCTION get_ids (
iVar IN NUMBER
)
RETURN ID_ID_ARRAY IS
lIds ID_ARRAY;
BEGIN
lids := get_ids0();
IF iVar = 1 THEN
lIds := concat(lFilter, get_ids1());
ELSE
lIds := concat(lFilter, get_ids3());
IF iVar = 4 THEN
lIds := concat(lFilter, get_ids4());
END IF;
END IF;
RETURN lIds;
END get_ids;
答案 0 :(得分:8)
如果您使用10g或更高版本,则可以使用MULTISET UNION运算符使CONCAT()函数更高效:
FUNCTION concat (
iList1 IN ID_ARRAY,
iList2 IN ID_ARRAY
)
RETURN ID_ARRAY IS
lConcat ID_ARRAY;
BEGIN
lConcat := iList1
MULTISET UNION
iList2 A
;
RETURN lConcat;
END concat;
你可以通过填充几个不同的数组,然后为所有数组调用一次MULTISET UNION来提高效率:
lConcat := iList1
MULTISET UNION
iList2
MULTISET UNION
iList3
MULTISET UNION
iList4;
使用动态SQL - 可能是为了替换各种get_idsN()
函数 - 可能是一种值得研究的方法,但可能不会给你提供太多(如果有的话)提高性能的方法。
临时表不是一个好主意,因为与在内存中做事相比,它们的表现非常糟糕。
答案 1 :(得分:4)
事实证明,有一种更简单的连接方式:
iList1 MULTISET UNION ALL iList2
(感谢https://forums.oracle.com/forums/thread.jspa?messageID=7420028。直到今天我才知道这是可能的。)