Преобразование `LISTAGG` В `XMLAGG`

Как преобразовать LISTAGG с операторами case в эквивалент XMLAGG, чтобы избежать ошибки конкатенации.

@ECHO ${cols_2 ||32767||varchar2}$ --Declare variable

SELECT LISTAGG( 'MAX(CASE WHEN CATEGORY = '''||CATEGORY||''' THEN "'||"LEVEL"||'" END) AS "'||"LEVEL"||'_'||CATEGORY||'"' , ',' )
          WITHIN GROUP( ORDER BY CATEGORY, "LEVEL" DESC )
    INTO cols_2
    FROM (
          SELECT DISTINCT "LEVEL", CATEGORY
            FROM temp
          );

Я попробовал это, и я получаю сообщение об ошибке missing keyword

@ECHO ${cols_2 ||32767||varchar2}$ --Declare variable

select rtrim (
          xmlagg (xmlelement (e, 'MAX(CASE WHEN CATEGORY = '''||CATEGORY||''' THEN "'||"LEVEL"||'" END) AS "'||LEVEL||'_'||CATEGORY||'"', ',') order by 1,2 desc).extract (
             '//text()'),
          ', ')
          INTO cols_2
    FROM (
          SELECT DISTINCT "LEVEL", CATEGORY
            temp
          );

Я пробовал это, объявляя cols_2 как тип clob: -

SELECT DBMS_XMLGEN.CONVERT (
           RTRIM (
               XMLAGG (XMLELEMENT (
                           e,
                              'MAX(CASE WHEN CATEGORY = '''
                           || CATEGORY
                           || ''' THEN "'
                           || "LEVEL"
                           || '" END) AS "'
                           || "LEVEL"
                           || '_'
                           || CATEGORY
                           || '"',
                           ',')
                       ORDER BY 1, DESC).EXTRACT('//text()').getclobval(),','),1)
               ', '),
           1)
  INTO cols_2
  FROM (SELECT DISTINCT "LEVEL", CATEGORY
          FROM temp);

Тем не менее, моя проблема не решена, я получаю сообщение об ошибке при попытке выполнить ее как процедуру, например: - Ошибка объединения функции `LISTAGG`[Не повторяющийся вопрос]


person Scope    schedule 05.10.2020    source источник


Ответы (1)


Вы получаете ошибку missing keyword, поскольку, скорее всего, пытаетесь выполнить второй запрос как отдельный запрос, а не в блоке PL/SQL. Когда вы это делаете, вы должны удалить пункт into cols_2. Это ваша непосредственная проблема, которая должна решить вашу ошибку.

Кроме того, исходя из вашего предыдущего вопроса, используя XML-функции будут экранировать ваши символы ' и ", поэтому вам нужно убедиться, что вы вернули их обратно в исходные символы, чтобы вы могли использовать их в своем динамическом запросе sql следующим образом:

SELECT DBMS_XMLGEN.CONVERT (
           RTRIM (
               XMLAGG (XMLELEMENT (
                           e,
                              'MAX(CASE WHEN CATEGORY = '''
                           || CATEGORY
                           || ''' THEN "'
                           || "LEVEL"
                           || '" END) AS "'
                           || "LEVEL"
                           || '_'
                           || CATEGORY
                           || '"',
                           ',')
                       ORDER BY 1, 2 DESC).EXTRACT ('//text()'),
               ', '),
           1)
  --INTO cols_2
  FROM (SELECT DISTINCT "LEVEL", CATEGORY
          FROM temp);
person EJ Egyed    schedule 05.10.2020
comment
Я попробовал ваш код с into v_cols2 внутри окна процедуры и без него, как у вас в окне SQL-командора, в обоих местах я получаю ошибку [Code: 19011, SQL State: 72000] ORA-19011: Character string buffer too small ORA-06512: at "PIVOT_VIEW"line 16 ORA-06512: at line 1 - person Scope; 06.10.2020
comment
Также я объявил переменную v_cols2 как long - person Scope; 06.10.2020
comment
Что такое "PIVOT_VIEW"? В операторе select нет ссылки на что-либо подобное. - person EJ Egyed; 06.10.2020
comment
Это просто имя моей процедуры, оно было успешно скомпилировано, но получило упомянутую ошибку, поэтому я просто хотел сообщить вам об ошибке, вы можете игнорировать часть имени. БД, а именно или даже оракул, в большинстве случаев показывает ошибку в процедуре определение, даже если это ошибка в блоке внутри него - person Scope; 06.10.2020
comment
Я посмотрел ТАК, во многих сообщениях говорится, что нам нужно addgetclobval(),',') , чтобы ошибка исчезла. Итак, я попробовал то же самое: ORDER BY 1, 2 DESC).EXTRACT ('//text()').getclobval(),','),1) компиляция прошла успешно, но пишет illegal zero length identifier - person Scope; 07.10.2020