【问题标题】:Cannot produce correct XML format using FOR XML PATH in SQL Server Stored Procedure无法在 SQL Server 存储过程中使用 FOR XML PATH 生成正确的 XML 格式
【发布时间】:2014-06-09 14:15:29
【问题描述】:

我是 XML 新手,我正在努力理解如何编写 SQL Server 存储过程以从下表生成 XML 文件。

Contract,ContractSection,ClaimReference,TransactionReference,ClaimReference,Ccy,PTT_Ind,PTT_Fees**
P000013-140, P000013-140_001, C000011-14, CLP00000036, C000011-14, GBP, 50, 100
P000066-888, P000066-888_001,   C000031-28, CLP00000041, C000011-14, GBP, 75, 200

我尝试使用FOR XML PATH 生成所需的格式,但未成功,如下所示:

<ReportingContractEntry>
    <Contract>
        <ReinsRef>P000013-140 </ReinsRef>
    <Contract>
    <ReportingSectionEntry>
        <SectionRef>P000013-140_001 </ SectionRef >
    </ReportingSectionEntry>
    <ReportingTransactionEntry>
<ReportingTransactionAmountEntry>
    <EntryReference>CLP00000036</EntryReference>
        <TechAccountAmtItem Type="ptt_ind">
            <Amt Share="reinsurer_share" Ccy="GBP">20.00</Amt>
    </TechAccountAmtItem>
        <TechAccountAmtItem Type="ptt_fees">
            <Amt Share="reinsurer_share" Ccy="GBP">590.00</Amt>
    </TechAccountAmtItem>
</ReportingTransactionAmountEntry>
</ReportingTransactionEntry>
</ReportingContractEntry>
<ReportingContractEntry>
    <Contract>
        <ReinsRef>P000066-888 </ReinsRef>
    <Contract>
    <ReportingSectionEntry>
        <SectionRef>P000013-140_001 </ SectionRef >
    </ReportingSectionEntry>
    <ReportingTransactionEntry>
<ReportingTransactionAmountEntry>
    <EntryReference>CLP00000041</EntryReference>
        <TechAccountAmtItem Type=" ptt_ind ">
            <Amt Share="reinsurer_share" Ccy="GBP">75.00</Amt>
    </TechAccountAmtItem>
        <TechAccountAmtItem Type="ptt_fees">
            <Amt Share="reinsurer_share" Ccy="GBP">200.00</Amt>
    </TechAccountAmtItem>
</ReportingTransactionAmountEntry>
</ReportingTransactionEntry>
</ReportingContractEntry>

到目前为止,我的最大努力是这样,但这仅适用于每个 ReportingTransactionEntry 的单个 TechAccountAmtItem。而且我需要添加多个TechAccountAmtItems

SELECT  
   RTRIM(policyRef) AS 'Contract/ReinsRef',
   RTRIM(policyRef) + '_001' AS 'ReportingSectionEntry/SectionRef',
   RTRIM(TransactionReference) AS 'ReportingTransactionEntry/ReportingTransactionAmountEntry/EntryReference' ,
   'ptt_ind' AS 'ReportingTransactionEntry/ReportingTransactionAmountEntry/TechAccountAmtItem/@Type',
   'reinsurer_share' AS 'ReportingTransactionEntry/ReportingTransactionAmountEntry/TechAccountAmtItem/Amt/@Share'  ,
   CASE WHEN currency_id = 26 THEN 'GBP' ELSE 'EUR' END AS 'ReportingTransactionEntry/ReportingTransactionAmountEntry/TechAccountAmtItem/Amt/@Ccy'  ,
   SUM(Paid_This_Time_Indemnity) AS 'ReportingTransactionEntry/ReportingTransactionAmountEntry/TechAccountAmtItem/Amt'
   --,SUM(Paid_This_Time_Fees) -- I can't figure out how to get a second <TechAmountItem> within the same <ReportingTransactionAmountEntry> ???????
FROM 
    #tmpClm2
GROUP BY
    policyRef, ClaimReference, TransactionReference, ClaimReference, currency_id
FOR XML PATH ('ReportingContractEntry')

正如我所说,XML 对我来说是全新的,因此非常感谢任何建议。

我什至不确定使用 FOR XML PATH 是否是解决此问题的正确方法。

这似乎是最简单、最灵活的选择。

【问题讨论】:

  • 您的架构中有两列名为“ClaimReference”。我不明白这是怎么回事。
  • 另外,您引用了policyRef,但此列未显示在您的架构中。清理它以减少混乱可能是个好主意。

标签: sql-server xml


【解决方案1】:

您示例中的架构与您的查询不对应,但问题很简单。在您的查询中,您可以使用希望返回多个元素的子查询。

代替:

   'ptt_ind' AS 'ReportingTransactionEntry/ReportingTransactionAmountEntry/TechAccountAmtItem/@Type',
    'reinsurer_share' AS 'ReportingTransactionEntry/ReportingTransactionAmountEntry/TechAccountAmtItem/Amt/@Share'  ,
    CASE WHEN currency_id = 26 THEN 'GBP' ELSE 'EUR' END AS 'ReportingTransactionEntry/ReportingTransactionAmountEntry/TechAccountAmtItem/Amt/@Ccy'  ,
    SUM(Paid_This_Time_Indemnity) AS 'ReportingTransactionEntry/ReportingTransactionAmountEntry/TechAccountAmtItem/Amt'

试试:

(
    SELECT * FROM
    (
        SELECT
        'ptt_ind' AS 'TechAccountAmtItem/@Type',
        'reinsurer_share' AS 'TechAccountAmtItem/Amt/@Share'  ,
        CASE WHEN currency_id = 26 THEN 'GBP' ELSE 'EUR' END AS 'TechAccountAmtItem/Amt/@Ccy'  ,
        SUM(Paid_This_Time_Indemnity) AS 'TechAccountAmtItem/Amt'
        UNION
        SELECT
        'ptt_fees' AS 'TechAccountAmtItem/@Type',
        'reinsurer_share' AS 'TechAccountAmtItem/Amt/@Share'  ,
        CASE WHEN currency_id = 26 THEN 'GBP' ELSE 'EUR' END AS 'TechAccountAmtItem/Amt/@Ccy'  ,
        SUM(Paid_This_Time_Fees) AS 'TechAccountAmtItem/Amt'
    ) iq FOR XML PATH(''), TYPE
) AS 'ReportingTransactionEntry/ReportingTransactionAmountEntry'

【讨论】:

  • 感谢您查看我格式错误的示例并发现问题。子查询修复了它。非常感谢
猜你喜欢
  • 2018-10-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-03
  • 2023-03-11
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多