2016-07-15 6 views
1

Ich versuche, SQL zu schreiben, um eine XML-Zeichenfolge mit untergeordneten Elementen zu generieren. Ich kann alles bekommen, aber die Kinder fallen nicht als Kinder, sie zeigen sich als separate Gegenstände auf der Wurzelebene. Ich habe mit der XML-Pfadangabe herumgespielt, aber ich habe einfach kein Glück.Schreiben von SQL zum Entwickeln von XML mit Kindern

Hilfe wäre willkommen. Ich bin auf einem SQL 2014-Server.

declare @xmldata xml 
set  @xmldata = ( SELECT adr.ACCOUNT_IDENTIFIER 
          , adr.FIRST_NAME 
          , adr.LAST_NAME 
          , adr.ADDR_LINE1 
          , adr.ADDR_LINE2 
          , adr.CITY 
          , adr.STATE 
          , adr.ZIP 
          , (SELECT ACCT_NBR 
            , LOAN_ORGL_PRIN_AMT 
            , LOAN_OSTD_PRIN_AMT 
            , LOAN_EFTV_INT_RT 
           FROM Staging.StatementOfBalance_SRC sob 
           WHERE sob.ACCT_NBR = crbr.ACCT_NBR 
           FOR XML path('accounts'), TYPE, elements) 
         from Staging.Account_Data crbr 
         join Unit_Cost.ADDRESSES_ALL adr on crbr.ACCOUNT_IDENTIFIER = adr.ACCOUNT_IDENTIFIER  
         FOR XML path('letter'), root ('statement'), elements ) 

SELECT @xmldata as returnXML 

Meine Ergebnisse sind

<statement> 
    <letter> 
     <ACCOUNT_IDENTIFIER>123321</ACCOUNT_IDENTIFIER> 
     <FIRST_NAME>Pippi</FIRST_NAME> 
     <LAST_NAME>Longstockings</LAST_NAME> 
     <ADDR_LINE1>123 Out Onna Boat</ADDR_LINE1> 
     <ADDR_LINE2 /> 
     <CITY>Ocean</CITY> 
     <STATE>ME</STATE> 
     <ZIP>000000</ZIP> 
     <accounts> 
      <ACCT_NBR>0000000000000000</ACCT_NBR> 
      <LOAN_ORGL_PRIN_AMT>2670.00</LOAN_ORGL_PRIN_AMT> 
      <LOAN_OSTD_PRIN_AMT>2749.09</LOAN_OSTD_PRIN_AMT> 
      <LOAN_EFTV_INT_RT>4.75000</LOAN_EFTV_INT_RT> 
     </accounts> 
    </letter> 
    <letter> 
     <ACCOUNT_IDENTIFIER>123321</ACCOUNT_IDENTIFIER> 
     <FIRST_NAME>Pippi</FIRST_NAME> 
     <LAST_NAME>Longstockings</LAST_NAME> 
     <ADDR_LINE1>123 Out Onna Boat</ADDR_LINE1> 
     <ADDR_LINE2 /> 
     <CITY>Ocean</CITY> 
     <STATE>ME</STATE> 
     <ZIP>000000</ZIP> 
     <accounts> 
      <ACCT_NBR>0000000000000000</ACCT_NBR> 
      <LOAN_ORGL_PRIN_AMT>4082.00</LOAN_ORGL_PRIN_AMT> 
      <LOAN_OSTD_PRIN_AMT>5520.21</LOAN_OSTD_PRIN_AMT> 
      <LOAN_EFTV_INT_RT>5.50000</LOAN_EFTV_INT_RT> 
     </accounts> 
    </letter> 
</statement> 

aber, was ich brauche ist:

<statement> 
     <letter> 
      <ACCOUNT_IDENTIFIER>123321</ACCOUNT_IDENTIFIER> 
      <FIRST_NAME>Pippi</FIRST_NAME> 
      <LAST_NAME>Longstockings</LAST_NAME> 
      <ADDR_LINE1>123 Out Onna Boat</ADDR_LINE1> 
      <ADDR_LINE2 /> 
      <CITY>Ocean</CITY> 
      <STATE>ME</STATE> 
      <ZIP>000000</ZIP> 
      <accounts> 
       <ACCT_NBR>0000000000000000</ACCT_NBR> 
       <LOAN_ORGL_PRIN_AMT>2670.00</LOAN_ORGL_PRIN_AMT> 
       <LOAN_OSTD_PRIN_AMT>2749.09</LOAN_OSTD_PRIN_AMT> 
       <LOAN_EFTV_INT_RT>4.75000</LOAN_EFTV_INT_RT> 
      </accounts> 
      <accounts> 
       <ACCT_NBR>0000000000000000</ACCT_NBR> 
       <LOAN_ORGL_PRIN_AMT>4082.00</LOAN_ORGL_PRIN_AMT> 
       <LOAN_OSTD_PRIN_AMT>5520.21</LOAN_OSTD_PRIN_AMT> 
       <LOAN_EFTV_INT_RT>5.50000</LOAN_EFTV_INT_RT> 
      </accounts> 
     </letter> 
    </statement> 

Antwort

1

Ich denke, das Problem Ihr in der äußeren SELECT verbinden ist ... Sie haben es nicht geben Sie Ihre Struktur, noch lieferten Sie Beispieldaten ...

Ihr tatsächlicher Ausgang verdoppelt die Vorlagenreihe, während Sie wünschen - mindestens die erwartete Ausgangspunkte dazu - eine 1: n-Beziehung zwischen Brief und Konto.

Ich habe versucht, Ihre Abfrage zu vereinfachen und erklärte Tabellen für die Abfrage passend, aber wegnahm scheint die Join-Tabelle und die Ausgabe in Ordnung sein: mein

DECLARE @letter TABLE(ACCOUNT_IDENTIFIER INT,FIRST_NAME VARCHAR(100),LAST_NAME VARCHAR(100)); 
INSERT INTO @letter VALUES(123321,'Pippi','Longstockings'); 
DECLARE @account TABLE(ACCOUNT_IDENTIFIER INT,ACCT_NBR VARCHAR(100), LOAN_ORGL_PRIN_AMT DECIMAL (14,4)); 
INSERT INTO @account VALUES(123321,'00000000000',2670.00),(123321,'00000000000',4082.00); 

SELECT 
     adr.ACCOUNT_IDENTIFIER 
    , adr.FIRST_NAME 
    , adr.LAST_NAME 
    --, adr.ADDR_LINE1 
    --, adr.ADDR_LINE2 
    --, adr.CITY 
    --, adr.STATE 
    --, adr.ZIP 
    , (SELECT ACCT_NBR 
      , LOAN_ORGL_PRIN_AMT 
      --, LOAN_OSTD_PRIN_AMT 
      --, LOAN_EFTV_INT_RT 
     FROM @account sob -- Staging.StatementOfBalance_SRC sob 
     WHERE sob.ACCOUNT_IDENTIFIER = adr.ACCOUNT_IDENTIFIER-- crbr.ACCT_NBR 
     FOR XML path('accounts'), TYPE, elements) 
from @letter adr --Staging.Account_Data crbr 
       --join Unit_Cost.ADDRESSES_ALL adr on crbr.ACCOUNT_IDENTIFIER = adr.ACCOUNT_IDENTIFIER  
FOR XML path('letter'), root ('statement') 

Das Ergebnis

<statement> 
    <letter> 
    <ACCOUNT_IDENTIFIER>123321</ACCOUNT_IDENTIFIER> 
    <FIRST_NAME>Pippi</FIRST_NAME> 
    <LAST_NAME>Longstockings</LAST_NAME> 
    <accounts> 
     <ACCT_NBR>00000000000</ACCT_NBR> 
     <LOAN_ORGL_PRIN_AMT>2670.0000</LOAN_ORGL_PRIN_AMT> 
    </accounts> 
    <accounts> 
     <ACCT_NBR>00000000000</ACCT_NBR> 
     <LOAN_ORGL_PRIN_AMT>4082.0000</LOAN_ORGL_PRIN_AMT> 
    </accounts> 
    </letter> 
</statement> 

So beraten:

Testen Sie diese ohne FOR XML PATH und gehen von außen nach innen. Zuerst sollten Sie glücklich sein mit

<statement> 
    <letter> 
    <ACCOUNT_IDENTIFIER>123321</ACCOUNT_IDENTIFIER> 
    <FIRST_NAME>Pippi</FIRST_NAME> 
    <LAST_NAME>Longstockings</LAST_NAME> 
    --more columns 
    </letter> 
</statement> 

Wenn dies funktioniert, definieren Sie Ihre Sub-Auswahl, um die entsprechenden Konten hinzuzufügen. Ihre Abfrage sieht tatsächlich ziemlich OK aus, also vermute ich, dass der Grund in den Relationen Ihrer Tabelle nicht so ist, wie Sie es erwarten ...

+0

Danke Shnugo! Ich hatte die WHERE im Inneren wählen Sie mit den Kontonummern, und nicht die Kontokennung. Matching Ihre Änderung hat es funktioniert. Glücklicher Montag :) – tracer

+0

WOOT! Ja, ich wollte sagen ... Ich bin nicht am magischen Ort ... habe UP gewählt! – tracer

Verwandte Themen