2009-04-16 3 views
1

Я думаю, что мне нужно CROSS APPLY, но я не могу понять синтаксис. У меня есть набор XML в базу данных MSSQL 2008, выглядит следующим образом:Mix XML Родители и дети в MSSQL

<Cookie> 
    <id>Chocolate Chip</id> 
    <ChocolateChipPeanutButter> 
     ... 
    </ChocolateChipPeanutButter> 

    <ChocolateChipPecan> 
     ... 
    </ChocolateChipPecan> 
</Cookie> 

<Cookie> 
    <id>Raisin</id> 
</Cookie> 

<Cookie> 
    <id>Coconut</id> 
</Cookie> 

<Cookie> 
    <id>Sugar</id> 
</Cookie> 

Я пытаюсь измельчить XML так, что у меня есть результирующий набор, который выглядит следующим образом:

Cookie Name     Cookie SubName 
___________     ______________ 
Chocolate Chip    <null> 
Chocolate Chip    ChocolateChipPeanutButter 
Chocolate Chip    ChocolateChipPecan 
Raisin      <null> 
Coconut      <null> 
Sugar       <null> 

Я думаю, что мне нужно написать что-то вроде этого (предположим, что данные XML хранятся в DECLARE @XMLData XML:

SELECT 
    TheXML.TheCookie.query('data(./id)')  AS CookieName 
    , TheXML.TheCookie.query('.')    AS CookieData 
    , Sub.SubCookieName      AS SubCookieName 
FROM 
    @XMLData.nodes('//Cookie') AS TheXML(TheCookie) 
CROSS APPLY 
    (
     SELECT 
      TheCookieXML.SubCookieName.query('local-name(.)') 
     FROM 
      CookieData.nodes('./*') AS TheCookieXML(SubCookieName) 
    ) 

Я знаю, я знаю, это XML-схема ужасна для что я пытаюсь сделать с этим, но давайте предположим, что мы застряли с данными таким образом и работаем оттуда. Я на правильном пути? Будет ли CROSS APPLY работать так? Может ли Бэтмен спасти меня сейчас?

+0

Прототип от Microsoft Cookie Master 2010 может быть :-) –

ответ

2

Попробуйте что-то вроде этого:

SELECT 
    TheXML.TheCookie.value('(id[1])', 'varchar(20)') AS CookieName 
    , TheXML.TheCookie.query('.') AS CookieData 
    , Sub.SubCookie.value('local-name(.)', 'varchar(20)') AS SubCookieName 
FROM 
    @xmlcon.nodes('//Cookie') AS TheXML(TheCookie) 
CROSS APPLY 
    TheXML.TheCookie.nodes('./*') as Sub(SubCookie) 

беда - это также выбирает "ID" узел :-(

Марк

+0

? TheXML.TheCookie.nodes ('./* [local-name()! =' Id ']) как Sub (SubCookie) – Tomalak

+0

отлично, спасибо, ребята! – brian

+2

Третья попытка комментария ... В приведенном выше изложении содержатся некоторые оговорки о пропущенных цитатах, ничего серьезного. Альтернативный, более простой XPath: TheXML.TheCookie.nodes ('./* [not (self :: id)]') – Tomalak