Oracle中的LISTAGG函数返回空值

3

如果一个列的值太长,Oracle 12c中的listagg函数会输出NULL。这是什么原因以及解决方法是什么呢?

SQL> select length(algo_desc) from r2_temp where DECL = '305';
     32759

ALGO_DESC非常长,例如1045、2339、2389……37364、58922、2389392。如果使用LISTAGG,则会返回NULL,如下所示:

SQL> select dump(listagg(algo_desc, ',') within group (order by algo_desc)) as algo_desc from r2_temp where DECL = '305';
     NULL

列ALGO_DESC的最大大小为32767,在12c中它是扩展varchar2类型。


1
listagg() 函数的长度受 varchar2()/nvarchar2() 的限制,通常为 4000 个字符左右。 - Gordon Linoff
我正在使用扩展的varchar2大小,即VARCHAR2(32767) - padmanabh pande
有趣。使用一些长值时,似乎会出现损坏,转储显示大量零(看起来像是错误19461687,但应该已经修复)。然后在某个时候,这种损坏表现为整体空值?也许是时候提出服务请求了? - Alex Poole
1个回答

0

作为一种解决方法,您可以使用此函数:

CREATE OR REPLACE TYPE VARCHAR_TABLE_TYPE AS TABLE OF VARCHAR2(32767);
-- or     CREATE OR REPLACE TYPE VARCHAR_TABLE_TYPE AS TABLE OF NUMBER;


CREATE OR REPLACE FUNCTION JoinTable(TAB IN VARCHAR_TABLE_TYPE, Joiner IN VARCHAR2) RETURN CLOB IS
    res CLOB;
BEGIN
    IF TAB IS NULL THEN 
        RETURN NULL; 
    END IF;
    IF TAB.COUNT = 0 THEN 
        RETURN NULL; 
    END IF;

    DBMS_LOB.CREATETEMPORARY(res, FALSE, DBMS_LOB.CALL);
    IF TAB(TAB.FIRST) IS NOT NULL THEN
        DBMS_LOB.APPEND(res, TAB(TAB.FIRST));
    END IF;
    IF TAB.COUNT > 1 THEN
        FOR i IN TAB.FIRST+1..TAB.LAST LOOP
            DBMS_LOB.APPEND(res, Joiner||TAB(i));
        END LOOP;
    END IF;
    RETURN res;

END JoinTable;



select JoinTable(CAST(COLLECT(algo_desc order by algo_desc) AS VARCHAR_TABLE_TYPE), ',') as algo_desc 
from r2_temp 
where DECL = '305';

1
谢谢您的输入。但是这个也不行,输出为NULL。 - padmanabh pande

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接