Какие есть альтернативы LISTAGG и WMCONCAT?

У меня есть запрос ниже -

SELECT   /*+ PARALLEL (CNVSO_TBAP_PRICE_PLAN ,16) FULL(CNVSO_TBAP_PRICE_PLAN) */
         AP_ID, MAIN_ITEM_ID,
         LISTAGG (AP_VERSION_ID || '_' || PARTITION_KEY
                          || '_'
                          || TO_CHAR (PARTITION_DATE, 'dd/mm/yyyy')) WITHIN GROUP(ORDER BY AP_VERSION_ID) AS LIST,
    FROM CNVSO_TBAP_PRICE_PLAN
GROUP BY AP_ID, MAIN_ITEM_ID;

Но получая ошибку -

ORA-01489: результат объединения строк слишком длинный

Если я использую WMCONCAT - запрос выполняется 11 часов (огромная таблица и худшая производительность WMCONCAT).

Я также пробовал XMLAGG, но получаю ошибку недопустимых аргументов:

SELECT   /*+ PARALLEL (CNVSO_TBAP_PRICE_PLAN ,16) FULL(CNVSO_TBAP_PRICE_PLAN) */
         AP_ID, MAIN_ITEM_ID,
         RTRIM (XMLAGG (XMLELEMENT (E, AP_VERSION_ID || '_' || PARTITION_KEY
                          || '_'
                          || TO_CHAR (PARTITION_DATE, 'dd/mm/yyyy')).EXTRACT ('//text()'), ',')) AS LIST,
         MAX (TO_NUMBER (AP_VERSION_ID)) MAX_AP_VERSION_ID
    FROM CNVSO_TBAP_PRICE_PLAN
GROUP BY AP_ID, MAIN_ITEM_ID;

Ваша помощь будет принята с благодарностью.. Заранее спасибо.


person user2446876    schedule 19.09.2018    source источник
comment
В Oracle 12.2 вы можете указать Oracle обрезать результат listagg(), когда он становится слишком длинным.   -  person a_horse_with_no_name    schedule 19.09.2018
comment
Прежде всего - спасибо за ваши правки. Не могли бы вы подробнее рассказать о том, как обрезать результаты? Кроме того, сократит ли это мой вывод? Потому что я должен использовать выходную строку как есть - я не могу позволить себе потерять данные в ней.   -  person user2446876    schedule 19.09.2018
comment
Вероятно, дубликат stackoverflow.com/q/42999390/1509264   -  person MT0    schedule 19.09.2018
comment
Новая опция усечения переполнения обрежет данные - так что вы потеряете эту информацию. Если 32 КБ достаточно, вы можете включить расширенные строки, а затем listagg должно сработать   -  person a_horse_with_no_name    schedule 19.09.2018
comment
Обычно я выполняю такие задачи, как эта, создавая функцию, которая считывает строки из CNVSO_TBAP_PRICE_PLAN в цикле построчно и добавляет их в clob. затем функция возвращает clob. тогда вы сможете сделать SELECT P.*,(SELECT AGG_TO_CLOB(P.AP_ID,P.MAIN_ITEM_ID) FROM DUAL) FROM ( SELECT AP_ID, MAIN_ITEM_ID FROM CNVSO_TBAP_PRICE_PLAN GROUP BY AP_ID, MAIN_ITEM_ID) P;. Еще лучше было бы использовать табличную функцию: SELECT * FROM TABLE(GET_PRICE_PLAN()); Надеюсь, это поможет .   -  person Peter    schedule 20.09.2018