0

我有这样的xml:

<root>
    <item>
        <Name>Pants</Name>
        <Value>No</Value>
    </item>
    <item>
        <Name>Other</Name>
        <Value>Yes</Value>
    </item>
</root>

<root>
    <item>
        <Name>Pants</Name>
        <Value>Yes</Value>
    </item>
    <item>
        <Name>Other</Name>
        <Value>Yes</Value>
    </item>
</root>

<root>
    <item>
        <Name>a</Name>
        <Value>b</Value>
    </item>
    <item>
        <Name>c</Name>
        <Value>d</Value>
    </item>
</root>

每个root元素都存储在 sql server 数据库的列中,我需要根据它创建列/行。我希望将“名称”作为列名并为该列填充值。也可能并不总是有 2 个<item>元素,可能更多或更少。

因此,当查询上述所有内容时,我想要:

|other columns|Pants|Other|a|c|<-column names
|~~~~~~~~~~~~~|No   |Yes  | | |<-rows
|~~~~~~~~~~~~~|Yes  |Yes  | | |
|~~~~~~~~~~~~~|     |     |b|d|

这甚至可能吗?

4

2 回答 2

1
SELECT 
   XMLColumnName.value('(/root/item/Name)[1]','varchar(max)') AS firstname,
   XMLColumnName.value('(/root/item/Value)[1]','varchar(max)') AS myValue

FROM MyTable

不知道您为什么<root>要按原样使用“ ”标签(通常整个 XML 值只有一个乞求和结束标签)。可能没有什么不同,但你必须看看。

于 2013-02-25T18:19:35.327 回答
1

使用动态数量的列,您需要动态 SQL。

首先使用您感兴趣的名称/值列表填充临时表。然后从临时表创建动态 SQL 语句并执行动态查询。

select ID,
       X.N.value('(Name/text())[1]', 'varchar(max)') as Name,
       X.N.value('(Value/text())[1]', 'varchar(max)') as Value
into #T
from T
  cross apply T.XMLCol.nodes('root/item') as X(N)

declare @SQL nvarchar(max)
declare @Col nvarchar(max)

select @Col = 
  (
  select distinct ','+quotename(Name)
  from #T
  for xml path(''), type
  ).value('substring(text()[1], 2)', 'nvarchar(max)')

set @SQL = 'select ID,'+@Col+'
            from #T
            pivot (max(Value) for Name in ('+@Col+')) as P'

exec (@SQL)

drop table #T

SQL小提琴

于 2013-02-26T14:22:52.717 回答