如何在pl sql中将聚合xml元素分组到另一个父xml标记内

时间:2016-02-03 07:40:02

标签: xml oracle

我有以下类型的存储在oracle数据库中的xml数据, 更新

    <employee>
    <id>123</id>
    <year>2016</year>
    <month>1</month>
    <paymstr_salhdnm>BASIC PAY</paymstr_salhdnm>    
    <paymstr_amount>440000</paymstr_amount>    
    <paymstr_salhdnm>ASSOCIATION SUBSCRIPTION</paymstr_salhdnm>
    <paymstr_amount>240</paymstr_amount>
    <paymstr_salhdnm>TELEPHONE ALLOWANCE</paymstr_salhdnm>
    <paymstr_amount>800</paymstr_amount>
    <paymstr_salhdnm>HOUSE RENT DEDUCTION</paymstr_salhdnm>
    <paymstr_amount>2587.5</paymstr_amount>
    <paymstr_salhdnm>MEDICAL ALLOWANCE</paymstr_salhdnm>
    <paymstr_amount>700</paymstr_amount>
    <paymstr_salhdnm>GAS BILL</paymstr_salhdnm>
    <paymstr_amount>450</paymstr_amount>
    </employee>

但我希望他们采用以下格式更新:

<employee>
 <id>123</id>
 <year>2016</year>
 <month>1</month>
<head>
<type>1</type>
<paymstr_salhdnm>BASIC PAY</paymstr_salhdnm>
<paymstr_amount>440000</paymstr_amount>
</head>
<head>
<type>1</type>
<paymstr_salhdnm>ASSOCIATION SUBSCRIPTION</paymstr_salhdnm>
<paymstr_amount>240</paymstr_amount>
</head>
<head>
<type>1</type>
<paymstr_salhdnm>TELEPHONE ALLOWANCE</paymstr_salhdnm>
<paymstr_amount>800</paymstr_amount>
</head>
<head>
<type>1</type>
<paymstr_salhdnm>HOUSE RENT DEDUCTION</paymstr_salhdnm>
<paymstr_amount>2587.5</paymstr_amount>
</head>
<head>
<type>1</type>
<paymstr_salhdnm>MEDICAL ALLOWANCE</paymstr_salhdnm>
<paymstr_amount>700</paymstr_amount>
</head>
<head>
<type>1</type>
<paymstr_salhdnm>GAS BILL</paymstr_salhdnm>
<paymstr_amount>450</paymstr_amount>
</head>
</employee>

这是我的pl sql代码更新:

      BEGIN   
   xmlData:=XMLType(master_file_data);
   employee_id := xmlData.extract('/employee_id/text()').getstringval();
   select   xmlElement(  "employee",
              xmlelement("id", e.PAYMSTR_EMPID),
              xmlelement("year", e.PAYMSTR_SALYR),
              xmlelement("month", e.PAYMSTR_SALMT),
              (select  XMLAGG(                
               xmlforest(  PAYMSTR_SALHDNM, PAYMSTR_AMOUNT  )                     
                 )
               from TBL_PAYROLL_MASTER_FILE s where  s.PAYMSTR_EMPID = e.PAYMSTR_EMPID and 
                  s.PAYMSTR_SALYR = e.PAYMSTR_SALYR and s.PAYMSTR_SALMT = e.PAYMSTR_SALMT)      
                      )   AS clob into ret
    from  
       ( select distinct PAYMSTR_EMPID, PAYMSTR_SALYR, PAYMSTR_SALMT 
         from  TBL_PAYROLL_MASTER_FILE where  PAYMSTR_EMPID = employee_id ) e;

 RETURN '<result><status >success</status>'||ret.getClobval()||'</result>';

我该怎么做。请帮我解决一下这个问题。请告诉我任何进一步的信息。谢谢

1 个答案:

答案 0 :(得分:1)

试试这个 -

 select 
        xmlagg
             (
              xmlelement("employee",
                    xmlelement("id", e.PAYMSTR_EMPID),
                    xmlelement("year", e.PAYMSTR_SALYR),
                    xmlelement("month", e.PAYMSTR_SALMT),
                    XMLAGG(
                        xmlelement("head",
                           xmlelement("type", 1), 
                           xmlelement("paymstr_salhdnm", salhdnm), 
                           xmlelement("paymstr_amount", amount))
                        )
                       )
              )
  into ret
  FROM tbl_payroll_master_file e
 WHERE e.PAYMSTR_EMPID = employee_id 
 GROUP BY e.PAYMSTR_EMPID, e.PAYMSTR_SALYR, e.PAYMSTR_SALMT;

例如:

declare 
    ret CLOB;
begin
    with e as
    (
        select 123 as paymstr_empid, 2016 as paymstr_salyr, 1 as paymstr_salmt, 'BASIC PAY' as salhdnm, 440000 as amount from dual union all
        select 123 as paymstr_empid, 2016 as paymstr_salyr, 1 as paymstr_salmt, 'ASSOCIATION SUBSCRIPTION' as salhdnm, 240 as amount from dual union all
        select 345 as paymstr_empid, 2016 as paymstr_salyr, 1 as paymstr_salmt, 'BASIC PAY' as salhdnm, 440000 as amount from dual union all
        select 345 as paymstr_empid, 2016 as paymstr_salyr, 1 as paymstr_salmt, 'ASSOCIATION SUBSCRIPTION' as salhdnm, 240 as amount from dual
    )
    select 
     xmlroot(
            XMLElement("result",
              XMLElement("status", 'success'),
                      XMLAGG
                         (
                          XMLElement("employee",
                                xmlelement("id", e.PAYMSTR_EMPID),
                                xmlelement("year", e.PAYMSTR_SALYR),
                                xmlelement("month", e.PAYMSTR_SALMT),
                                XMLAGG(
                                    xmlelement("head",
                                       xmlelement("type", 1), 
                                       xmlelement("paymstr_salhdnm", salhdnm), 
                                       xmlelement("paymstr_amount", amount))
                                    )
                                   )
                          )
                      ),
                  version '1.0" encoding="utf-8'
           ).getClobVal() as xml_data
    into ret
    from e
    group by e.PAYMSTR_EMPID, e.PAYMSTR_SALYR, e.PAYMSTR_SALMT;
   dbms_output.put_line(ret);
end;