将listagg函数限制为前4000个字符

时间:2015-02-03 14:34:02

标签: sql oracle oracle11g varchar2

我有一个查询,它使用listagg函数将所有行作为逗号分隔的字符串,最终传送到一个大文本框。我得到以下例外:

ORA-01489: result of string concatenation is too long

我知道问题是正在运行以聚合数据的查询返回了很多行,而listagg正在执行的字符串连接违反了4000个字符串限制。但是,对于我的用例,截断到前4000个字符是完全可以接受的。

如何从here修改此示例查询以限制"值"列最多4000个字符?

SELECT LISTAGG(product_name, ', ') WITHIN GROUP( ORDER BY product_name DESC) "Product_Listing" FROM products

你无法绕过substr listagg listagg' because substr`调用throws the exception before

我已经看到很多关于如何绕过4000个字符限制的问题,但不限制结果值。

1 个答案:

答案 0 :(得分:6)

分析函数可以生成字符串聚合的运行总长度。然后内联视图可以删除长度大于4000的任何值。

在真实查询中,您可能需要向分析函数添加partition by,以便仅对某个组进行计数。

--The first 4000 characters of PRODUCT_NAME.
select
    --Save a little space for a ' ...' to imply that there is more data not shown.
    case when max(total_length) > 3996 then
        listagg(product_name, ', ') within group (order by product_name)||
            ' ...'
    else
        listagg(product_name, ', ') within group (order by product_name)
    end product_names
from
(
    --Get names and count lengths.
    select
        product_name,
        --Add 2 for delimiters.
        sum(length(product_name) + 2) over (order by product_name) running_length,
        sum(length(product_name) + 2) over () total_length
    from products
    order by product_name
)
where running_length <= 3996

这里有一个SQL Fiddle来证明这个问题。