2016-07-16 5 views
0

私は、監査履歴をXML形式で格納するテーブルを持っています。各ドキュメントには独自の履歴があります。どのようにしてXMLデータを解析することができますか。XMLの各列とその列で実際に発生した列と動作を表します。XMLを列に分割するSQLスクリプト

例:

<auditElement><field id="2881159" type="5" name="Responsiveness" formatstring=""><unSetChoice>2881167</unSetChoice><setChoice>2881166</setChoice></field></auditElement>

UnsetChoiceと設定の選択は列です。 名前=アクションを表します。

答えて

0

XXXはXQueryまたはOpenXmlなどの機能を使用して解析できます。ここで

は、XQueryの例です:

declare @xml as xml = '<auditElement><field id="2881159" type="5" name="Responsiveness"' + 
        ' formatstring=""><unSetChoice>2881167</unSetChoice>' + 
        '<setChoice>2881166</setChoice></field></auditElement>'; 

SELECT 
    Nodes.node.value('(field/@id)[1]', 'INT') AS FieldId, 
    Nodes.node.value('(field/@name)[1]', 'varchar(50)') AS FieldName, 
    Nodes.node.value('(field/unSetChoice/text())[1]', 'INT') AS OldValue, 
    Nodes.node.value('(field/setChoice/text())[1]', 'INT') AS NewValue 
FROM 
    @xml.nodes('//auditElement') AS Nodes(node); 

結果:

FieldId  FieldName           OldValue NewValue 
----------- -------------------------------------------------- ----------- ----------- 
2881159  Responsiveness          2881167  2881166 
+0

。例:xmlデータが10行あった場合、宣言を読み込み、結果を出力するにはどうすればよいですか? – Jeff

0

あなたがOUTERを適用し、XMLフィールドの一部を打破することができます。

value()の方法は、XQueryの式が必要です。例えば

DECLARE @T TABLE (Id int identity(1,1) primary key, XmlCol1 xml); 

insert into @T (XmlCol1) values 
('<auditElement><field id="2881159" type="5" name="Responsiveness" formatstring=""><unSetChoice>2881167</unSetChoice><setChoice>2881166</setChoice></field></auditElement>'), 
('<auditElement><field id="2881160" type="6" name="Responsiveness" ><unSetChoice>2881187</unSetChoice><setChoice>2881188</setChoice></field></auditElement>'); 

select * 
from ( 
    select 
    Id, 
    a.field.value('@id', 'int') as xmlid, 
    a.field.value('(unSetChoice)[1]', 'int') as unSetChoice, 
    a.field.value('(setChoice)[1]', 'int') as setChoice, 
    a.field.value('@type', 'int') as type, 
    a.field.value('@name', 'varchar(max)') as name, 
    a.field.value('@formatstring', 'varchar(max)') as formatstring 
    from @T t 
    outer apply t.XmlCol1.nodes('/auditElement/field') as a(field) 
    where a.field.value('@id', 'int') > 0 and Id > 0 
) q 
where name = 'Responsiveness'; 

結果:私が与えたサンプルの複数の行を格納されているテーブルを持っていたものならば

Id xmlid unSetChoice setChoice type name   formatstring 
1 2881159 2881167  2881166  5  Responsiveness 
2 2881160 2881187  2881188  6  Responsiveness NULL 
+0

これは正しい道のりですが、xmlデータを持つ異なる文書IDによって異なる表をどのように読み取ることができますか?つまり、ループを使わなくても、異なる文書IDごとにxmlデータの行を含む表を読み込み、表示された形式でデータを出力する宣言を行う方法があります。ここでは、作成したテーブルの例を示します:CREATE TABLE #AuditHistoryForQuery(DocumentArtifactID INT、[名前] nvarchar(500)、[HashValue] VARCHAR(100)、[ActionString] nvarchar(100)、[UserName] varchar(200) 、DetailsXML XML、[TimeStamp] datetime) – Jeff

+0

where句を追加し、いつものようにその一時テーブルから必要な行を選択するだけです。また、抽出されたxml値に基づいて選択する場合は、SQLをサブクエリに配置し、外側のクエリにwhere句を追加できます。 – LukStorms

+0

Btw、この例では、テーブルに2行を挿入しました。しかし、2つのauditElementが1行しかない場合、同じ結果が得られます。 1つの違いがあります。結果は同じIDになります。 – LukStorms

関連する問題