代码之家  ›  专栏  ›  技术社区  ›  afeef

如何在xmltable oracle中使用group by

  •  0
  • afeef  · 技术社区  · 6 年前

    当我使用 group by 在XML表中,它抛出错误:

    ORA-01422:精确获取返回多个请求的行数

    我尝试使用listagg()函数作为解决方案,但它没有解决问题。

    我的SQL

       SELECT xmlelement("logs", xmlagg(xmlelement("log", xmlforest(v1.column_1 as "id", v1.column_2 as "name")))).getclobval()
       INTO   v_output 
       FROM   xmltable( '/logs/log' passing xmltype(in_xml) columns id number path 
      'id' ) x 
     JOIN   view v1 
     ON     v1.id= x.id;
    

    输入XML

    declare
      in_xml clob := '<?xml version="1.0" encoding="UTF-8"?>
        <logs>
            <log>
                <id>123456</id>
            </log>
            <log>
                <id>456898</id>
            </log>
        </logs>';
      v_output clob;
    
    begin
    
       select xmlelement("logs", xmlagg(xmlelement("log", xmlforest(v1.column_1 as "id", v1.column_2 as "name")))).getclobval()
      into v_output
      from xmltable(
        '/logs/log'
        passing xmltype(in_xml)
        columns id number path 'id'
      ) x
      join view v1 on v1.id = x.id
     GROUP BY  v1.id;
    
      dbms_output.put_line (v_output);
    
    end;
    

    任何解决方案都是最受欢迎的。

    1 回复  |  直到 6 年前
        1
  •  1
  •   Sentinel    6 年前

    您的第一个查询与最初编写的一样好,但是,在第二个代码块中,您引入了 group by 子句,该子句可能使查询返回多条记录,但您正试图将它们选入单个输出变量。

    您需要将查询限制为单个id,或者将v_输出更改为clob值的集合并使用批量操作:

    declare
      in_xml clob := '<?xml version="1.0" encoding="UTF-8"?>
        <logs>
            <log>
                <id>123456</id>
            </log>
            <log>
                <id>456898</id>
            </log>
        </logs>';
      type t_clob is table of clob;
      v_output t_clob;
    
    begin
    
       select xmlelement("logs", xmlagg(xmlelement("log", xmlforest(v1.column_1 as "id", v1.column_2 as "name")))).getclobval()
      bulk collect into v_output
      from xmltable(
        '/logs/log'
        passing xmltype(in_xml)
        columns id number path 'id'
      ) x
      join view v1 on v1.id = x.id
     GROUP BY  v1.id
     fetch first 10 rows only;
    
     for iter in v_output.first .. v_output.last loop
       dbms_output.put_line (v_output);
     end loop;   
    end;
    

    如果在v_u输出中选择了大量的行,那么在没有获取限制的情况下,应该对上面的代码尽可能小心,因为它可能会耗尽可用内存。目前,只有前10条记录将被检索并写出。