2016-07-06 16 views
3

我似乎很難與XML。我正在尋找適當的身份證附加到每行XML查詢附加適當的ID

Declare @User table (id int,First_Name varchar(50),Last_Name varchar(50),EMail varchar(50)) 
Insert into @User values 
(1,'John','Smith','[email protected]'), 
(2,'Jane','Doe' ,'[email protected]') 

Declare @XML xml 
Set @XML = (Select * from @User for XML RAW) 

Select ID = 1 -- < dummy need actual id 
     ,Item = cast(x.v.query('local-name(.)') as varchar(100)) 
     ,Value = x.v.value('.','varchar(150)') 
From @xml.nodes('//@*') x(v) 

我目前的結果是。

ID Item  Value 
1 id   1 
1 First_Name John 
1 Last_Name Smith 
1 EMail  [email protected] 
1 id   2 
1 First_Name Jane 
1 Last_Name Doe 
1 EMail  [email protected] 

期望結果將是。

ID Item  Value 
1 id   1 
1 First_Name John 
1 Last_Name Smith 
1 EMail  [email protected] 
2 id   2 
2 First_Name Jane 
2 Last_Name Doe 
2 EMail  [email protected] 
+0

這是一個很好的問題:Copy'n'pasteable測試場景,自己的努力,錯誤的產出,預期的產出和明確而簡短的描述。如果更多的問題是這樣的...... :-)投了票! – Shnugo

+0

Bo!我感到尷尬......謝謝! – Shnugo

+0

@Shnugo不要尷尬,我已經從你的帖子中獲得了很多里程 –

回答

4

試試這樣說:

順便說一句:你是非常接近!

Declare @User table (id int,First_Name varchar(50),Last_Name varchar(50),EMail varchar(50)) 
Insert into @User values 
(1,'John','Smith','[email protected]'), 
(2,'Jane','Doe' ,'[email protected]') 

Declare @XML xml 
Set @XML = (Select * from @User for XML RAW) 

SELECT @XML; 

/* 
<row id="1" First_Name="John" Last_Name="Smith" EMail="[email protected]" /> 
<row id="2" First_Name="Jane" Last_Name="Doe" EMail="[email protected]" /> 
*/ 

第一.nodes()將與單排 的CROSS APPLY .nodes(./@*)會做所有屬性基於行的搜索,並提供它們作爲單個行中的所有元素row返回。

Select r.value('@id','int') AS ID 
     ,Attr.value('local-name(.)','varchar(max)') AS Item 
     ,Attr.value('.','varchar(max)') AS Value 
FROM @XML.nodes('/row') AS A(r) 
CROSS APPLY A.r.nodes('./@*') AS B(Attr) 
+0

FABULOUS!我嘗試了無數種組合。非常感謝你。 –

+0

不錯的工作..我無法找到行過濾器'('./@*')'任何地方..我確實發現這一點,但如果你想排除id行..'CROSS APPLY Arnodes('。/@ * [local-name(。)!=「id」]')' – JamieD77

+0

@ JamieD77,好暗示......由於* id在*期望的輸出中被提及,所以我會認爲它是想要的...... – Shnugo

1

剛剛遇到了這個問題。儘管已經給出了這個問題的答案,但是想到用不同的方法來回答它,而不使用xquery。

可以使用CROSS APPLYTable Value Constructor這樣實現同樣的結果 -

Declare @User table (id int,First_Name varchar(50),Last_Name varchar(50),EMail varchar(50)) 
Insert into @User values 
(1,'John','Smith','[email protected]'), 
(2,'Jane','Doe' ,'[email protected]') 

SELECT r.ID, t.* FROM @User r 
CROSS APPLY (
    VALUES ('ID', cast(id as varchar)), 
      ('First_Name', First_Name), 
      ('Last_Name', Last_Name), 
      ('EMail', EMail) 
) t(Item, Value) 

結果

ID Item  Value 
--------------------- 
1 ID   1 
1 First_Name John 
1 Last_Name Smith 
1 EMail  [email protected] 
2 ID   2 
2 First_Name Jane 
2 Last_Name Doe 
2 EMail  [email protected] 
+0

欣賞答案,我是這種技術的忠實粉絲,但對於原始問題,我正在尋找一種動態方法+1 –