2012-11-07 13 views
5

Sto provando a modificare un xml di terze parti in modo che tutti gli elementi abbiano ID di T-SQL.come assegnare gli ID ai nodi xml nello stesso livello

Questa è l'XML originale (sezione):

<Tables> 
    <Table Type="LineItem"> 
     <TableRow> 
     <Field Name="LI_NominalCode" Type="wd_lit_nominalcode">244234</Field> 
     <Field Name="LI_NominalDesc" Type="lit_nominaldesc">RENT RECEIVABLE - INTERNAL</Field> 
     <Field Name="LI_Account" Type="lit_wd_account" /> 
     <Field Name="LI_AccountDesc" Type="lit_wd_accountdesc" /> 
     <Field Name="LI_SecondAccount" Type="lit_wd_2ndaccount" /> 
     <Field Name="LI_SecondAccountDesc" Type="lit_wd_2ndaccountdesc" /> 
     <Field Name="LI_NetValue" Type="lit_vatexcludedamount">4522.89</Field> 
     <Field Name="LI_EnergyUsage" Type="wd_energyusage">56666</Field> 
     <Field Name="LI_EnergyType" Type="wd_energytype">ELECTRICITY</Field> 
     </TableRow> 
     <TableRow> 
     <Field Name="LI_NominalCode" Type="wd_lit_nominalcode">150021</Field> 
     <Field Name="LI_NominalDesc" Type="lit_nominaldesc">Rent Building 1</Field> 
     <Field Name="LI_Account" Type="lit_wd_account" /> 
     <Field Name="LI_AccountDesc" Type="lit_wd_accountdesc" /> 
     <Field Name="LI_SecondAccount" Type="lit_wd_2ndaccount" /> 
     <Field Name="LI_SecondAccountDesc" Type="lit_wd_2ndaccountdesc" /> 
     <Field Name="LI_NetValue" Type="lit_vatexcludedamount">456.37</Field> 
     <Field Name="LI_EnergyUsage" Type="wd_energyusage">2805.00</Field> 
     <Field Name="LI_EnergyType" Type="wd_energytype">ELECTRICITY</Field> 
     </TableRow> 
     <TableRow> 
     <Field Name="LI_NominalCode" Type="wd_lit_nominalcode">2342341</Field> 
     <Field Name="LI_NominalDesc" Type="lit_nominaldesc">Rent Building 2</Field> 
     <Field Name="LI_Account" Type="lit_wd_account" /> 
     <Field Name="LI_AccountDesc" Type="lit_wd_accountdesc" /> 
     <Field Name="LI_SecondAccount" Type="lit_wd_2ndaccount" /> 
     <Field Name="LI_SecondAccountDesc" Type="lit_wd_2ndaccountdesc" /> 
     <Field Name="LI_NetValue" Type="lit_vatexcludedamount">355</Field> 
     <Field Name="LI_EnergyUsage" Type="wd_energyusage">6900</Field> 
     <Field Name="LI_EnergyType" Type="wd_energytype">ELECTRICITY</Field> 
     </TableRow> 
    </Table> 
    <Table Type="BankAccountTable" /> 
    <Table Type="VATTable" /> 
    </Tables> 

Come si può vedere, le <Table> elementi non hanno ID, così più tardi nel processo è difficile identificarli.

Mi piacerebbe creare un ciclo per passare attraverso tutti i <Table> elementi ed eseguire un frammento come questo:

set @xml.modify(' 
insert attribute ID {sql:variable("@idString")} 
into (/Documents/Document/Invoice/Tables/Table[@Type="LineItem"]/TableRow)[sql:variable("@id")]') 

Il problema si trova sul l'ultima variabile SQL, l'errore è:

XQuery [modify()]: Only 'http://www.w3.org/2001/XMLSchema#decimal?', 'http://www.w3.org/2001/XMLSchema#boolean?' or 'node()*' expressions allowed as predicates, found 'xs:string ?'

Questo funziona bene, ma non voglio cambiare sempre la stessa riga (numero 1).

set @xml.modify(' 
insert attribute ID {sql:variable("@idString")} 
into (/Documents/Document/Invoice/Tables/Table[@Type="LineItem"]/TableRow)[1]') 

A proposito, se uso una variabile int invece di una stringa come ad esempio:

set @xml.modify('insert attribute ID {sql:variable("@idString")} 
       into (/Documents/Document/Invoice/Tables/Table[@Type="LineItem"]/TableRow)[sql:variab‌​le("@idInt")]')` 

ottengo un altro errore:

XQuery [modify()]: The target of 'insert' must be a single node, found 'element(TableRow,xdt:untyped) *

risposta

2

È possibile confrontare la variabile @id di funzionare position().

declare @id int 
declare @RowCount int 
select @RowCount = @xml.value('count(/Tables/Table[@Type="LineItem"]/TableRow)', 'int') 

set @id = 1 

while @id <= @RowCount 
begin 
    set @xml.modify(' 
    insert attribute ID {sql:variable("@id")} 
    into (/Tables/Table[@Type="LineItem"]/TableRow[position()=sql:variable("@id")])[1]') 

    set @id = @id + 1 
end 
+0

Genio! Ha funzionato come un incantesimo, non era ovvio, poiché anche [1] può essere usato per indicare la posizione dell'elemento. – checamon

1

L'unica cosa che posso venire con è una procedura memorizzata con tutte le righe possibili (sentito qualcuno che scarica lo sciacquone?)

if (@row = 1) 
BEGIN 
    set @xml.modify(' 
     insert attribute ID {sql:variable("@id")} 
     into (/Documents[1]/Document[1]/Invoice[1]/Tables[1]/Table[@Type="LineItem"][1]/TableRow)[1] 
     ') 
END 
ELSE if (@row = 2) 
BEGIN 
    set @xml.modify(' 
     insert attribute ID {sql:variable("@id")} 
     into (/Documents[1]/Document[1]/Invoice[1]/Tables[1]/Table[@Type="LineItem"][1]/TableRow)[2] 
     ') 
END 
ELSE if (@row = 3) 
BEGIN 
    set @xml.modify(' 
     insert attribute ID {sql:variable("@id")} 
     into (/Documents[1]/Document[1]/Invoice[1]/Tables[1]/Table[@Type="LineItem"][1]/TableRow)[3] 
     ') 
END 

Speriamo che non sarà più di 200 ...

Problemi correlati