2016-07-06 2 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

Boah! Я чувствую смущение ... Спасибо! – Shnugo

+0

@Shnugo Не смущайся, я получил много пробега из твоих сообщений –

ответ

4

Попробуйте так:

Btw: Вы были очень близки!

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() вернется со всеми 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) 
+0

FABULOUS! Я пробовал бесчисленные комбинации. Огромное спасибо. –

+0

хорошая работа .. я не смог найти фильтр строк '('./@*')' в любом месте .. я нашел это, хотя если вы хотите исключить строку id .. 'CROSS APPLY Arnodes ('./@ * [local-name (.)! = "id"] ') ' – JamieD77

+0

@ JamieD77, хороший намек ... Поскольку« id »упоминается в желаемом выпуске, я бы предположил, что это нужно ... – Shnugo

1

Только что наткнулся на этот вопрос. Хотя ответ на этот вопрос уже был дан, он решил ответить на него с помощью другого подхода, не используя xquery.

Вы можете достичь того же результата, используя CROSS APPLY и Table 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 –

Смежные вопросы