将“LISTAGG”转换为“XMLAGG”

Posted

技术标签:

【中文标题】将“LISTAGG”转换为“XMLAGG”【英文标题】:Convert ` LISTAGG` TO `XMLAGG` 【发布时间】:2020-10-05 18:13:59 【问题描述】:

如何将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);

但我的问题还没有解决,我在尝试执行它时遇到错误,例如:- Error in concatenation of `LISTAGG` function[Not a duplicate question]

【问题讨论】:

【参考方案1】:

您收到missing keyword 错误,因为您很可能尝试将第二个查询作为独立查询而不是在 PL/SQL 块中运行。当你这样做时,你必须删除你的 into cols_2 子句。这是您的直接问题,应该可以解决您的错误。

此外,根据您的 prior question,使用 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);

【讨论】:

我在过程窗口中使用into v_cols2 尝试了您的代码,没有在 SQL comander 窗口中使用它,这两个地方我都得到[Code: 19011, SQL State: 72000] ORA-19011: Character string buffer too small ORA-06512: at "PIVOT_VIEW"line 16 ORA-06512: at line 1 错误 我也将v_cols2 变量声明为long 什么是"PIVOT_VIEW"?在 select 语句中没有任何类似的引用。 这只是我的程序名,它编译成功了,但是得到了提到的错误,所以我只是想让你知道错误,你可以忽略名称部分。DB viz甚至oracle most有时在 proc 定义中显示错误,即使它在其中的块中出现错误 我查了一下,很多帖子说我们需要 addgetclobval(),',') 才能消除错误。所以我尝试了同样的方法:ORDER BY 1, 2 DESC).EXTRACT ('//text()').getclobval(),','),1) 编译成功但它说illegal zero length identifier

以上是关于将“LISTAGG”转换为“XMLAGG”的主要内容,如果未能解决你的问题,请参考以下文章

查询将过去 11 个会计年度作为行返回。我可以使用 LISTAGG() 将其转换为逗号分隔的列表吗?

listagg 数据转换为可用格式?

Amazon Redshift 中 LISTAGG 函数的替代方法

listagg 列转换

oracle的LISTAGG函数 和 REGEXP_SUBSTR函数的使用

oracle的LISTAGG函数 和 REGEXP_SUBSTR函数的使用