2015-02-03 3 views
2

У меня есть запрос, который использует функцию listagg, чтобы получить все строки в виде строки с разделителями-запятыми, которые в конечном итоге будут отправлены в большое текстовое поле. Я получаю следующее исключение:Ограничить функцию listagg до первых 4000 символов

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' because listagg throws the exception before substr` никогда не вызывается.

Я видел много вопросов о том, как преодолеть ограничение 4000 символов, но не ограничивать полученное значение.

ответ

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, показывая запрос.

Смежные вопросы