1

I'm trying to shred a table of XML documents into SQL Server columns and am going around in circles with one bit.

Basically I have a table (ID int, XMLData XML) and each row will contain a document in the XML column.

I need to turn it into the following format

(
ID int, 
ReferenceCurrency varchar, 
TargetCurrency varchar, 
ReferenceAmount decimal, 
TargetAmount decimal, 
DueDate date
)

I've cut down this table.

The code I have inherited was a mix of XML.value and string searches with charindex which haven't been too reliable.

This is a snippet of the message we have.

<ReferenceCurrency>
      <Ccy>GBP</Ccy>
</ReferenceCurrency>
<TargetCurrency>
      <Ccy>USD</Ccy>
</TargetCurrency>    
<BalanceAmtItem Type="technical_account_settlement_balance_due_to_sender">
      <Amt Ccy="USD" CcyIndic="reference_currency" Share="receiver_share">65.62</Amt>
      <Amt Ccy="USD" CcyIndic="target_currency" Share="receiver_share">96.62</Amt>
      <DueDate>2019-09-04</DueDate>
</BalanceAmtItem>

I can get most of the data just using XML.value

SELECT 
    ID, 
    XMLDATA.value('(Jv-Ins-Reinsurance/TechAccount/ReferenceCurrency)[1]', 'varchar(4)') AS ReferenceCurrency ,
    XMLDATA.value('(Jv-Ins-Reinsurance/TechAccount/TargetCurrency)[1]', 'varchar(4)') AS TargetCurrency,
    XMLDATA.value('(Jv-Ins-Reinsurance/TechAccount/BalanceAmtItem/DueDate)[1]', 'date') AS DueDate
FROM
    dta

The bit I'm struggling with is how to get the two amount columns where CcyIndic = reference_currency or target_currency.

In this example I would expect to get a single line of 1, GBP, USD, 65.62, 96.62, 2019-09-04

Any help appreciated.

2 Answers 2

1

SQL

-- DDL and sample data population, start
DECLARE @tbl TABLE(ID INT IDENTITY(1,1) PRIMARY KEY, XMLData XML);
INSERT INTO @tbl
VALUES
(N'<Jv-Ins-Reinsurance>
    <TechAccount>
        <ReferenceCurrency>
            <Ccy>GBP</Ccy>
        </ReferenceCurrency>
        <TargetCurrency>
            <Ccy>USD</Ccy>
        </TargetCurrency>
        <BalanceAmtItem Type="technical_account_settlement_balance_due_to_sender">
            <Amt Ccy="USD" CcyIndic="reference_currency" Share="receiver_share">65.62</Amt>
            <Amt Ccy="USD" CcyIndic="target_currency" Share="receiver_share">96.62</Amt>
            <DueDate>2019-09-04</DueDate>
        </BalanceAmtItem>
    </TechAccount>
</Jv-Ins-Reinsurance>');
-- DDL and sample data population, end

SELECT ID, 
    c.value('(ReferenceCurrency/Ccy)[1]', 'varchar(4)') AS ReferenceCurrency ,
    c.value('(TargetCurrency/Ccy)[1]', 'varchar(4)') AS TargetCurrency,
    c.value('(BalanceAmtItem/Amt[@CcyIndic="reference_currency"])[1]', 'MONEY') AS ref_money,
    c.value('(BalanceAmtItem/Amt[@CcyIndic="target_currency"])[1]', 'MONEY') AS target_money,
    c.value('(BalanceAmtItem/DueDate)[1]', 'date') AS DueDate
FROM @tbl AS tbl
CROSS APPLY tbl.xmldata.nodes('/Jv-Ins-Reinsurance/TechAccount') AS t(c);
Sign up to request clarification or add additional context in comments.

Comments

1

Something like this:

declare @doc xml = 
'<ReferenceCurrency>
      <Ccy>GBP</Ccy>
</ReferenceCurrency>
<TargetCurrency>
      <Ccy>USD</Ccy>
</TargetCurrency>    
<BalanceAmtItem Type="technical_account_settlement_balance_due_to_sender">
      <Amt Ccy="USD" CcyIndic="reference_currency" Share="receiver_share">65.62</Amt>
      <Amt Ccy="USD" CcyIndic="target_currency" Share="receiver_share">96.62</Amt>
      <DueDate>2019-09-04</DueDate>
</BalanceAmtItem>';

SELECT 
   -- ID, 
    XMLDATA.value('(/ReferenceCurrency)[1]', 'varchar(4)') AS ReferenceCurrency,
    XMLDATA.value('(/TargetCurrency)[1]', 'varchar(4)') AS TargetCurrency,
    XMLDATA.value('(/BalanceAmtItem/Amt[@CcyIndic="reference_currency"])[1]', 'varchar(4)') AS ReferenceAmount ,
    XMLDATA.value('(/BalanceAmtItem/Amt[@CcyIndic="target_currency"])[1]', 'varchar(4)') AS TargetAmount ,
    XMLDATA.value('(/BalanceAmtItem/DueDate)[1]', 'date') AS DueDate
FROM
    (select @doc XMLDATA) d

outputs

ReferenceCurrency TargetCurrency ReferenceAmount TargetAmount DueDate
----------------- -------------- --------------- ------------ ----------
GBP               USD            65.6            96.6         2019-09-04

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.