XML查询附加适当的ID

时间:2016-07-06 15:10:08

标签: sql-server xml tsql xpath sql-server-2012

我似乎很难用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','john.smith@gmail.com'),
(2,'Jane','Doe'  ,'jane.doe@gmail.com')

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       john.smith@gmail.com
1   id          2
1   First_Name  Jane
1   Last_Name   Doe
1   EMail       jane.doe@gmail.com

我的所需结果将是。

ID  Item        Value
1   id          1
1   First_Name  John
1   Last_Name   Smith
1   EMail       john.smith@gmail.com
2   id          2
2   First_Name  Jane
2   Last_Name   Doe
2   EMail       jane.doe@gmail.com

2 个答案:

答案 0 :(得分:4)

试试这样:

顺便说一下:你非常接近!

Declare @User table (id int,First_Name varchar(50),Last_Name varchar(50),EMail varchar(50))
Insert into @User values
(1,'John','Smith','john.smith@gmail.com'),
(2,'Jane','Doe'  ,'jane.doe@gmail.com')

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

SELECT @XML;

/*
<row id="1" First_Name="John" Last_Name="Smith" EMail="john.smith@gmail.com" />
<row id="2" First_Name="Jane" Last_Name="Doe" EMail="jane.doe@gmail.com" />
*/

第一个.nodes()将返回单行中的所有row元素 CROSS APPLY .nodes(./@*)将对所有属性进行基于行的搜索,并将它们作为单行传递。

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)

答案 1 :(得分: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','john.smith@gmail.com'),
(2,'Jane','Doe'  ,'jane.doe@gmail.com')

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       john.smith@gmail.com
2   ID          2
2   First_Name  Jane
2   Last_Name   Doe
2   EMail       jane.doe@gmail.com