Способ перечисления XML-объектов в SQL Server с использованием методов XML? - PullRequest
0 голосов
/ 10 октября 2011

SQL Server 2005/2008.

Я искал и читал несколько вопросов здесь и в других местах, а также в BOL, но ни один из тех, что я нашел до сих пор, прямо не отвечает на этот вопрос.

С учетом

declare @xml xml = '<Root> <Ent foo="abc" bar="def" /> </Root>'

Есть ли способ получить набор результатов, например,

col1        col2
-----------------
foo         abc
bar         def

Я знаю, как это сделать, используя sp_xml_preparedocument и OPENXML, мне просто интересно, есть ли способ сделать это напрямую, используя методы xml. Я не смог ничего найти в BOL или Googling, но просто хотел убедиться, что ничего не пропустил.

Спасибо!

Ответы [ 3 ]

3 голосов
/ 10 октября 2011

Это может дать вам отправную точку, чтобы получить то, что вам нужно.

DECLARE @xml xml = N'<Root> <Ent foo="abc" bar="def" /> </Root>';

WITH [Attributes]([xml])
AS
(
    SELECT
        @xml.query
        ('
            for $x in (/Root/Ent/@*)
            return <attribute name="{local-name($x)}" value="{data($x)}"/>
        ')
)
SELECT
    [Attribute].[data].value(N'@name', N'nvarchar(max)') AS [col1],
    [Attribute].[data].value(N'@value', N'nvarchar(max)') AS [col2]
FROM
    [Attributes]
CROSS APPLY
    [xml].nodes(N'attribute') AS [Attribute]([data]);
2 голосов
/ 11 октября 2011

Как правило, метод query () работает медленнее, чем value ().Поэтому я рекомендую использовать метод value ():

 SELECT
    b.value('local-name(.)','nvarchar(MAX)') as col1,
    b.value('data(.)','nvarchar(MAX)') as col2
FROM @xml.nodes('//Root/Ent/@*') a(b)

По сравнению с предыдущим ответом он примерно в 3 раза быстрее.

1 голос
/ 10 октября 2011

В SQL Server 2005/2008 вы можете использовать эти два XML-метода : @xml.nodes() и @xml.value.

--Test1
DECLARE @xml XML = '<Root> <Ent foo="abc" bar="def"/> </Root>';
SELECT   col1 = 'foo', col2 = @xml.value('(/Root/Ent/@foo)[1]','NVARCHAR(10)') 
UNION ALL       
SELECT   col1 = 'bar', col2 = @xml.value('(/Root/Ent/@bar)[1]','NVARCHAR(10)');

--Test2
SELECT  @xml = '<Root> <Ent> <Node a="foo" b="abc"/> <Node a="bar" b="def"/> </Ent> </Root>';
SELECT   col1 = x.node.value('@a','NVARCHAR(100)') 
        ,col2 = x.node.value('@b','NVARCHAR(100)')
FROM    @xml.nodes('/Root/Ent/Node') x(node)

Результаты:

col1 col2
---- ----------
foo  abc
bar  def
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...