2016-07-16 5 views
0

감사 내역을 XML 형식으로 저장하는 테이블이 있습니다. 각 문서에는 자체 기록이 있습니다. 문서의 XML 데이터를 파싱하려면 XML의 각 열과 그 열에서 발생한 실제 열과 동작을 파싱하는 방법을 사용합니다.XML을 사용하여 XML을 열로 나누기

예 :

<auditElement><field id="2881159" type="5" name="Responsiveness" formatstring=""><unSetChoice>2881167</unSetChoice><setChoice>2881166</setChoice></field></auditElement>
이 UnsetChoice 및 설정 선택을 열 수 있습니다. 이름 = 작업을 나타냅니다.

답변

0

XXX는 XQuery 또는 OpenXml과 같은 기능을 사용하여 구문 분석 할 수 있습니다.

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 APPLY를 사용하고 XML 필드의 부품을 분해 할 수

여기에 xquery의 예입니다.

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 행을 삽입했습니다. 그러나 두 auditElement가 단 한 행에 있으면 동일한 결과를 얻습니다. 좋아, 1 차이 : 결과는 단지 같은 이드 것입니다. – LukStorms