Ошибка при использовании listagg в oracle «Слишком длинная конкатенация строк» - PullRequest
0 голосов
/ 19 марта 2020

У меня есть таблица типа temp_a, в которой есть:

acc ai_tab   where
A   B        QQQQ
A   B        RRRR
C   D        SSSS
C   D        TTTT

В столбце where хранится слишком большая строка. Итак, мой ожидаемый вывод

acc ai_tab where 
A   B      QQQQ RRRR
C   D      SSSS TTTT

Я пытался добиться этого с помощью:

 select acc,ai_tab,LISTAGG(WHERE,'') WITHIN GROUP ORDER BY (acc) "where_cond2" from temp_a
group by acc,ai_tab;

Я получил ошибку как:

ORA-01489 :result of string concatenation is too long.

Я искал этот похожий вопрос и говорит, что использовать XMLCLOB также, но он не работает? Можем ли мы использовать функцию, чтобы получить это или есть какие-либо другие методы?

Ответы [ 2 ]

2 голосов
/ 19 марта 2020

Вот пример, который показывает обе опции, которые вы можете использовать; если listagg не удалось, попробуйте xmlagg.

SQL> SELECT RTRIM (
  2            XMLAGG (XMLELEMENT (e, ename || ' ') ORDER BY empno).EXTRACT (
  3               '//text()'),
  4            ', ')
  5            employees_1,
  6         --
  7         LISTAGG (ename, ' ') WITHIN GROUP (ORDER BY empno) employees_2
  8    FROM emp
  9   WHERE deptno = 10;

EMPLOYEES_1                    EMPLOYEES_2
------------------------------ ------------------------------
CLARK KING MILLER              CLARK KING MILLER

SQL>
1 голос
/ 19 марта 2020

Согласен с решением Littlefoot. В качестве альтернативы вы могли бы написать свою собственную функцию. Я включил образец ниже. Примечание: я не проверял это с вашими данными, поэтому не уверен, насколько хорошо это будет работать

    SQL> create table foo as
         select 'A' acc, 'B' ai_tab, 'QQQQ' where_column from dual union all
         select 'A','B','RRRR' from dual union all
         select 'C','D','SSSS' from dual union all
         select 'C','D','TTTT' from dual;

    Table created.

    SQL> select * from foo;

    ACC AI_TAB WHERE_COLUMN
    --  --     ----
    A   B      QQQQ
    A   B      RRRR
    C   D      SSSS
    C   D      TTTT

    SQL> create or replace function str_concat (
             p_acc       in  foo.acc%type,
             p_ai_tab    in  foo.ai_tab%type
             )
         return clob
         is
             l_concat  clob;
         begin
         for o in ( 
                 select where_column from foo where acc = p_acc and ai_tab =  p_ai_tab  
             ) loop
                     l_concat := l_concat || ' ' || o.where_column;
                 end loop;
             return ltrim(l_concat, ' ');
         end;
         /

    Function created.

    SQL> select acc, ai_tab, where_column from (
         select acc, ai_tab, str_concat(acc, ai_tab) where_column, row_number() over (partition by acc, ai_tab order by null)
         ) where rn = 1;

    ACC AI_TAB  WHERE_COLUMN
    --  --      ----
    A   B       QQQQ RRRR
    C   D       SSSS TTTT
...