2016-05-26 4 views
0

Ich habe eine Tabelle updates, jede Zeile hat eine id Spalte und eine XML-Spalte namens changes. Die XML-Spalte für jede Zeile haben Werte wie:SQL Server Xpath, um Text Wert für bestimmte XML-Element

<changes> 
    <update> 
    <field>assignedto</field> 
    <oldvalue>c713826</oldvalue> 
    <newvalue>Trainer</newvalue> 
    </update> 
    <update> 
    <field>status</field> 
    <oldvalue>inprogress</oldvalue> 
    <newvalue>query</newvalue> 
    </update> 
    <update> 
    <field>note</field> 
    <oldvalue /> 
    <newvalue>January 2016 or 2017?</newvalue> 
    </update> 
</changes> 

Ich möchte den Wert von newvalue und oldvalue wo field = "AssignedTo" für jeden Datensatz zu finden. Das Feld AssignedTo wird immer nur einmal im XML für jeden Datensatz angezeigt. Um wieder nur Datensätze mit dem AssignedTo Feld

Bisher habe ich

where [changes].exist('/changes/update/field/text() [contains(.,"assignedto")]') 

verwendet, aber ich habe Schwierigkeiten, die passenden alten und neuen Werte auswählen.

Antwort

3

Sie können die Daten aus dem XML wie folgt wählen:

declare @data xml 
select @data = '<changes> 
    <update> 
    <field>assignedto</field> 
    <oldvalue>c713826</oldvalue> 
    <newvalue>Trainer</newvalue> 
    </update> 
    <update> 
    <field>status</field> 
    <oldvalue>inprogress</oldvalue> 
    <newvalue>query</newvalue> 
    </update> 
    <update> 
    <field>note</field> 
    <oldvalue /> 
    <newvalue>January 2016 or 2017?</newvalue> 
    </update> 
</changes>' 

select 
    T.C.value('oldvalue[1]', 'nvarchar(max)') as oldvalue, 
    T.C.value('newvalue[1]', 'nvarchar(max)') as newvalue 
from @data.nodes('changes/update') as T(C) 
where T.C.value('field[1]', 'nvarchar(max)') = 'assignedto' 

Im Fall der Spalte aus der Tabelle der Auswahl wird es so etwas wie

select * 
from dbo.updates as U 
    outer apply 
    (
     select 
      T.C.value('oldvalue[1]', 'nvarchar(max)') as oldvalue, 
      T.C.value('newvalue[1]', 'nvarchar(max)') as newvalue 
     from U.[changes].nodes('changes/update') as T(C) 
     where T.C.value('field[1]', 'nvarchar(max)') = 'assignedto' 
    ) as CALC 
where 
    CALC.oldvalue is not null 
    or CALC.newvalue is not null 
+0

sein wollte gerade fragen, wie man sich bewirbt, dass zu einem Tisch, aber du hast mich dazu geschlagen. Vielen Dank – Jammy

Verwandte Themen