【问题标题】:Concatenating collections in PLSQL连接 PLSQL 中的集合
【发布时间】:2011-11-18 15:26:41
【问题描述】:

我需要从几个不同的表中收集大量 id 到某种变量中,然后传递给另一个函数。从哪些表中获取 id 是动态的,具体取决于下面的参数 iVar。问题是是否没有更好的方法来做到这一点,因为这种方法必须多次复制和重新分配数组。将它全部插入临时表会更好吗?使用动态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;

【问题讨论】:

    标签: sql oracle plsql user-defined-types


    【解决方案1】:

    如果您使用的是 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() 函数 - 可能是一种值得研究的方法,但可能不会给您带来太多的改进性能。

    临时表不是一个好主意,因为与在内存中做事相比,它们的性能非常糟糕。

    【讨论】:

      【解决方案2】:

      原来有一种更简单的连接方式:

      iList1 MULTISET UNION ALL iList2
      

      (感谢https://forums.oracle.com/forums/thread.jspa?messageID=7420028。直到今天我才知道这是可能的。)

      【讨论】:

      • ALL 是可选的。 MULTISET UNION 无论如何都不会过滤条目。
      • 应该是“不排序或过滤”8-)
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-09-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多