2016-11-30 19 views
0

我有以下XML,我想使用Oracle生成生成XML。使用Oracle

<Component ID="600564" asmid="1" def="FactSheet" type="Document"> 
    <Profile> 
     <Port_ID>182</Port_ID> 
     <Inception_Date>31 Dec 1998</Inception_Date> 
    </Profile> 
    <AverageAnnualReturns> 
     <TableData> 
      <Item> 
       <ClassID>33</ClassID> 
       <ClassName>A1USD</ClassName> 
       <Superscript>2</Superscript> 
       <Superscript_TCE/>    
      </Item> 
      <Item> 
       <ClassID>45</ClassID> 
       <ClassName>I1EUR</ClassName> 
       <Superscript>1,2</Superscript> 
       <Superscript_TCE/>    
      </Item> 
     </TableData> 
     <SuppressLifeColumn>Yes</SuppressLifeColumn> 
     <SuppressBenchColumn10yr>No</SuppressBenchColumn10yr> 
     <SuppressBenchColumn5yr>No</SuppressBenchColumn5yr> 
     <SuppressBenchColumn3yr>No</SuppressBenchColumn3yr> 
     <SuppressBenchColumn1yr>No</SuppressBenchColumn1yr> 
    </AverageAnnualReturns> 
</Component> 

查詢爲輪廓遵循

SELECT PCR.PORT_ID, 
to_char(p.port_start_dt, 'dd Mon yyyy') as INCEPTION_DATE 
FROM edp_admin.PORT_CLASS_REPORT PCR 
JOIN edp_admin.PORTFOLIO p on (PCR.PORT_ID = P.PORT_ID and PCR.CLASS_ID = P.BASE_CLASS_ID) 
where PCR.PORT_ID = 182 AND PCR.REPORT_ID = 472 

查詢爲AverageAnnualReturn是遵循

SELECT distinct MPR.PORT_ID, 
MPR.CLASS_ID, 
MPR.CLASS_NAME, 
PCR.VALUE_NUM3 as RANK, 
NVL (NC.SUPERSCRIPT_TEXT,' ') as SUPERSCRIPT_TEXT 
FROM EDP_ADMIN.SYSTEM_VALUE PCR 
LEFT JOIN EDP_ADMIN.MPR_MIL_VIEW MPR ON (PCR.VALUE_NUM1 = MPR.PORT_ID AND PCR.VALUE_NUM2 = MPR.CLASS_ID AND MPR.CLASSIF_ID = 206) 
LEFT JOIN EDP_ADMIN.PORT_CLASS_YIELD PCY ON (PCR.VALUE_NUM1 = PCY.PORT_ID AND PCR.VALUE_NUM2 = PCY.CLASS_ID AND MPR.PROFILE_DATE = PCY.PORT_CLASS_YIELD_DT AND PCY.YIELD_ID = 6) 
LEFT JOIN EDP_ADMIN.PORTFOLIO_CLASS PC ON (PCR.VALUE_NUM1 = PC.PORT_ID AND PCR.VALUE_NUM2 = PC.CLASS_ID) 
LEFT JOIN EDP_ADMIN.PORT_CLASS_MKT_PRICE PCMP ON (PCR.VALUE_NUM1 = PCMP.PORT_ID AND PCR.VALUE_NUM2 = PCMP.CLASS_ID AND PCMP.MKT_PRICE_ID = 12 AND MPR.PROFILE_DATE = PCMP.PORT_CLA_MKT_PRICE_PER_END_DT) 
LEFT JOIN (SELECT DISTINCT R1.PORT_ID, R1.CLASS_ID, R1.PORT_CLASS_EXP_RAT_VALUE, R1.PORT_CLASS_EXP_RAT_DT FROM edp_admin.Port_Class_Expense_Ratio R1 INNER JOIN (SELECT DISTINCT PORT_ID, CLASS_ID, MAX(PORT_CLASS_EXP_RAT_DT) as MONTH_END_DATE FROM EDP_ADMIN.PORT_CLASS_EXPENSE_RATIO GROUP BY PORT_ID, CLASS_ID) R2 ON (R1.PORT_ID = R2.PORT_ID AND R1.CLASS_ID = R2.CLASS_ID AND R1.PORT_CLASS_EXP_RAT_DT = R2.MONTH_END_DATE)) PCER ON PCR.VALUE_NUM1 = PCER.PORT_ID and PCR.VALUE_NUM2 = PCER.CLASS_ID 
LEFT JOIN EDP_ADMIN.FN_MIL_FS_CONCAT_NOTES_VIEW NC ON NC.PORT_ID = PCR.VALUE_NUM1 AND NC.CLASS_ID = PCR.VALUE_NUM2 AND NC.HYPO_TYPE = PCR.VALUE_CHAR1 
WHERE PCR.CODE = 'MIL_FS_PERF_CONFIG' AND PCR.VALUE_NUM1 IN (182) AND PCR.VALUE_CHAR1 = 'UK' ORDER BY RANK 

我試圖使用Oracle SQL函數用於產生象​​下面

select dbms_xmlquery.getxml(sql for profile) from dual 

XML但它克enerates兩個額外的XML節點的行集和行像下面

<?xml version = '1.0'?> 
<ROWSET> 
    <ROW num="1"> 
     <PORT_ID>182</PORT_ID> 
     <INCEPTION_DATE>31 Dec 1998</INCEPTION_DATE>  
    </ROW> 
</ROWSET> 

另一種方法是

select xmlelement("Component",xmlattributes('600564' as ID, 
              '1' as asmid, 
              'FactSheet' as def, 
              'Document' as type 
              ), 
        xmlagg(
        xmlelement("Profile") 

       )            

      )from dual 

它產生結構如下圖

<Component ID="600564" ASMID="1" DEF="FactSheet" TYPE="Document"><Profile></Profile></Component> 

,但我不geeting我怎麼填充下數據profile節點然後averageannualreturns

回答

2

您可以使用潛艇選擇以獲取profileaverageannualreturns節點的數據。例如:

select xmlelement("Component", 
     xmlattributes('600564' as ID, 
         '1' as asmid, 
         'FactSheet' as def, 
         'Document' as type 
     ), 
     (
     SELECT XMLELEMENT("Profile", 
        XMLFOREST(
        'example_port' AS "Port_ID", 
        '30/11/2016' as "Inception_Date" 
       ) 
       ) 
     FROM dual 
     )         
) from dual; 

我相信這是諸如此類的事情,你需要(雖然我沒有你的表來測試):使用appendChildXML和PLSQL

select xmlelement("Component", 
     xmlattributes('600564' as ID, 
         '1' as asmid, 
         'FactSheet' as def, 
         'Document' as type 
     ), 
     (
     SELECT XMLELEMENT("Profile", 
        XMLFOREST(
        PCR.PORT_ID AS "Port_ID", 
        to_char(p.port_start_dt, 'dd Mon yyyy') as "Inception_Date" 
       ) 
       ) 
     FROM edp_admin.PORT_CLASS_REPORT PCR 
     JOIN edp_admin.PORTFOLIO p on (PCR.PORT_ID = P.PORT_ID and PCR.CLASS_ID = P.BASE_CLASS_ID) 
     where PCR.PORT_ID = 182 AND PCR.REPORT_ID = 472 
     ), 
     (
      SELECT XMLELEMENT("AverageAnnualReturns", 
        XMLELEMENT("TableData", 
        XMLAGG(
         XMLELEMENT("Item", 
         XMLFOREST(
          MPR.CLASS_ID AS "ClassID", 
          MPR.CLASS_NAME AS "ClassName", 
          NVL (NC.SUPERSCRIPT_TEXT,' ') AS "SuperScript", 
          NULL AS "SuperScript_TCE" 
         ) 
         ) 
        ) 
        ), 
        XMLFOREST(
        'Yes' AS "SupressLifeColumn", 
        'No' AS "SupressBenchColumn10yr", 
        'No' AS "SupressBenchColumn5yr", 
        'No' AS "SupressBenchColumn3yr", 
        'No' AS "SupressBenchColumn1yr" 
        ) 
       ) 
      FROM EDP_ADMIN.SYSTEM_VALUE PCR 
      LEFT JOIN EDP_ADMIN.MPR_MIL_VIEW MPR ON (PCR.VALUE_NUM1 = MPR.PORT_ID AND PCR.VALUE_NUM2 = MPR.CLASS_ID AND MPR.CLASSIF_ID = 206) 
      LEFT JOIN EDP_ADMIN.PORT_CLASS_YIELD PCY ON (PCR.VALUE_NUM1 = PCY.PORT_ID AND PCR.VALUE_NUM2 = PCY.CLASS_ID AND MPR.PROFILE_DATE = PCY.PORT_CLASS_YIELD_DT AND PCY.YIELD_ID = 6) 
      LEFT JOIN EDP_ADMIN.PORTFOLIO_CLASS PC ON (PCR.VALUE_NUM1 = PC.PORT_ID AND PCR.VALUE_NUM2 = PC.CLASS_ID) 
      LEFT JOIN EDP_ADMIN.PORT_CLASS_MKT_PRICE PCMP ON (PCR.VALUE_NUM1 = PCMP.PORT_ID AND PCR.VALUE_NUM2 = PCMP.CLASS_ID AND PCMP.MKT_PRICE_ID = 12 AND MPR.PROFILE_DATE = PCMP.PORT_CLA_MKT_PRICE_PER_END_DT) 
      LEFT JOIN (SELECT DISTINCT R1.PORT_ID, R1.CLASS_ID, R1.PORT_CLASS_EXP_RAT_VALUE, R1.PORT_CLASS_EXP_RAT_DT FROM edp_admin.Port_Class_Expense_Ratio R1 INNER JOIN (SELECT DISTINCT PORT_ID, CLASS_ID, MAX(PORT_CLASS_EXP_RAT_DT) as MONTH_END_DATE FROM EDP_ADMIN.PORT_CLASS_EXPENSE_RATIO GROUP BY PORT_ID, CLASS_ID) R2 ON (R1.PORT_ID = R2.PORT_ID AND R1.CLASS_ID = R2.CLASS_ID AND R1.PORT_CLASS_EXP_RAT_DT = R2.MONTH_END_DATE)) PCER ON PCR.VALUE_NUM1 = PCER.PORT_ID and PCR.VALUE_NUM2 = PCER.CLASS_ID 
      LEFT JOIN EDP_ADMIN.FN_MIL_FS_CONCAT_NOTES_VIEW NC ON NC.PORT_ID = PCR.VALUE_NUM1 AND NC.CLASS_ID = PCR.VALUE_NUM2 AND NC.HYPO_TYPE = PCR.VALUE_CHAR1 
      WHERE PCR.CODE = 'MIL_FS_PERF_CONFIG' AND PCR.VALUE_NUM1 IN (182) AND PCR.VALUE_CHAR1 = 'UK' ORDER BY RANK 
     )         
) from dual; 

解決方案:

DECLARE 
    lComponentXML xmltype; 
    lProfileXML xmltype; 
BEGIN 
    --generate the component xml 
    select xmlelement("Component", 
      xmlattributes('600564' as ID, 
         '1' as asmid, 
         'FactSheet' as def, 
         'Document' as type 
      ) 
     ) 
    INTO lComponentXML 
    FROM dual; 

    --generate the profile xml 
    SELECT XMLELEMENT("Profile", 
      XMLFOREST(
      PCR.PORT_ID AS "Port_ID", 
      to_char(p.port_start_dt, 'dd Mon yyyy') as "Inception_Date" 
      ) 
     ) 
    INTO lProfileXML 
    FROM edp_admin.PORT_CLASS_REPORT PCR 
    JOIN edp_admin.PORTFOLIO p on (PCR.PORT_ID = P.PORT_ID and PCR.CLASS_ID = P.BASE_CLASS_ID) 
    where PCR.PORT_ID = 182 AND PCR.REPORT_ID = 472; 

    --append the profile xml to the component 
    lComponentXML := lComponentXML.appendChildXML('//Component',lProfileXML); 
END; 
+0

它的工作,但如果我在SQL中使用不同的或ORDER BY這是行不通的。在sql中爲AverageAnnulReturns使用了distinct和order by,它在執行時失敗 – yatinbc

+0

有一件事情也是我頭腦中最重要的一點,我將如何在生成它的xml等效結構之前將業務條件應用於每個sql。 – yatinbc

+0

如果您使用的是plsql,我已經添加了一個額外的解決方案,該解決方案將允許您在將XML附加到主體XML主體之前對其應用業務條件。我可能會建議單獨構建每個XML塊,然後逐漸添加它。這樣,你可以得到每個小塊的和獨特的使用條款的順序工作,並逐步增加他們在 – Chrisrs2292