Domanda

Sto cercando di generare qualche XML con vari livelli di nidificazione, e con il rischio di un eccesso di semplificazione, l'XML uscita sarà liberamente del formato:

<invoice number="1">
 <charge code="foo" rate="123.00">
  <surcharge amount="10%" />
 </charge>
 <charge code="bar" />
</invoice>

Lo schema del database ho ereditato questo succede ad avere oneri memorizzati nelle tabelle diverse, il che significa che le maggiorazioni vengono memorizzati in modo diverso in base alla tabella da cui l'accusa era da.

Dato che si non è possibile utilizzare UNIONs con FOR XML , ho fatto un po 'di UNIONing in un CTE, in modo da qualcosa lungo la linee di:

WITH Charges ( [@code], [@rate], surcharge, InvoiceId ) AS (
    SELECT code AS [@Code], amount AS [@rate], NULL as surcharge, InvoiceId
    FROM item.charges
UNION ALL
    SELECT 
        code AS [@Code], 
        amount AS [@rate],
        (
             SELECT amount AS [@amount]
             FROM order.surcharges os
             WHERE oc.ChargeId = os.ChargeId
             FOR XML PATH('surcharge'), TYPE
        ), 
        InvoiceId
    FROM order.charges oc
)
SELECT
    Number AS [@number],
    (
         SELECT
             [@code],
             [@rate],
             surcharge
         FROM Charges
         WHERE Charges.InvoiceId = i.InvoiceId
    )
FROM Invoices i
FOR XML PATH( 'invoice' ), TYPE

Ora, che è incredibilmente close, dando (Si noti la <surcharge> nidificato):

<invoice number="1">
 <charge code="foo" rate="123.00">
  <surcharge>
   <surcharge amount="10%" />
  </surcharge>
 </charge>
 <charge code="bar" />
</invoice>

Ma ho bisogno di trovare un modo di ottenere la query fine di includere il valore di una colonna XML da trattare come il contenuto dell'elemento, piuttosto che come un nuovo elemento. Questo è possibile, o ho bisogno di prendere un nuovo approccio?

È stato utile?

Soluzione 2

Sembra che la denominazione della colonna (falso), come "*" userà che il contenuto di quella colonna come il contenuto dell'elemento, in modo da cambiare la SQL come di seguito lo fa funzionare:

WITH Charges ( [@code], [@rate], surcharge, InvoiceId ) AS (
    SELECT code AS [@Code], amount AS [@rate], NULL as surcharge, InvoiceId
    FROM item.charges
UNION ALL
    SELECT 
        code AS [@Code], 
        amount AS [@rate],
        (
             SELECT amount AS [@amount]
             FROM order.surcharges os
             WHERE oc.ChargeId = os.ChargeId
             FOR XML PATH('surcharge'), TYPE
        ), 
        InvoiceId
    FROM order.charges oc
)
SELECT
    Number AS [@number],
    (
         SELECT
             [@code],
             [@rate],
             surcharge AS [*] -- Thsi will embed the contents of the previously generated XML in here.
         FROM Charges
         WHERE Charges.InvoiceId = i.InvoiceId
    )
FROM Invoices i
FOR XML PATH( 'invoice' ), TYPE

Altri suggerimenti

È una query di colonna, che restituisce le righe mulitple mi aspetterei la query si registra per dare l'errore (@charge, @rate, e un tipo di XML.):

  

Una sola espressione può essere specificata   nell'elenco di selezione quando il subquery   Non viene introdotto con EXISTS.

Tuttavia, questo è facilmente risolto spostando la query a un outer apply. Per rimuovere l'elemento doppio surcharge, è possibile spostare i nomi delle colonne XML come molto più a fondo possibile, come:

;WITH Charges (code, rate, surcharge, InvoiceId) AS 
    (
    SELECT  code, amount, NULL, InvoiceId
    FROM    @charges
    UNION ALL
    SELECT  code
    ,       amount
    ,       (
            SELECT  amount AS [@amount]
            FROM    @surcharges os
            WHERE   oc.ChargeId = os.ChargeId
            FOR XML PATH('surcharge'), TYPE
            )
    ,       InvoiceId
    FROM    @charges oc
)
SELECT  Number AS [@number]
,       c.code as [charge/@code]
,       c.rate as [charge/@rate]
,       c.surcharge as [charge]
FROM    @Invoices i
outer apply
        (
        SELECT  code
        ,       rate
        ,       surcharge
        FROM    Charges
        WHERE   Charges.InvoiceId = i.InvoiceId
        ) c
WHERE   i.InvoiceID = 1
FOR XML PATH( 'invoice' ), TYPE

Questa sarebbe la stampa, ad esempio:

<invoice number="1">
  <charge code="1" rate="1" />
</invoice>
<invoice number="1">
  <charge code="1" rate="1">
    <surcharge amount="1" />
  </charge>
</invoice>

Il primo elemento viene dalla parte superiore del sindacato, dove surcharge = null.

Penso che si può fare questo omettendo il tipo di nodo principale nel vostro "per XML Path ( 'a pagamento')" dichiarazione. Cioè, l'uso "per il percorso xml ( '')", invece.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top