Sql 如何将XML行转换为列

Sql 如何将XML行转换为列,sql,sql-server,xml,Sql,Sql Server,Xml,我已经看到了一些关于如何将行转换为列的答案,但是这些答案对于这些问题来说非常具体,并且很难转换为我自己的解决方案 数据开始时是一个varchar,但我将其转换为XML,因为我认为这样将其转换为列会更容易 -- get xml DECLARE @x XML SET @x = '<ul><li>Gas grill rotisserie</li><li>Fits the Genesis E-300 gas grill</li><li&

我已经看到了一些关于如何将行转换为列的答案,但是这些答案对于这些问题来说非常具体,并且很难转换为我自己的解决方案

数据开始时是一个varchar,但我将其转换为XML,因为我认为这样将其转换为列会更容易

-- get xml
DECLARE @x XML

SET @x = '<ul><li>Gas grill rotisserie</li><li>Fits the Genesis E-300 gas grill</li><li>Fits the Genesis S-300 gas grill</li><li>Includes a heavy-duty electric motor</li><li>Counterbalance for smooth turning and less motor wear</li></ul>'

SELECT x.r.value('node()[1]','varchar(200)')
FROM @x.nodes('/ul/li') AS x(r)
这将返回如下结果:;但是,我现在需要将每一行转换为一列

我已经尝试过使用pivot和DynamicSQL的变体,但还没走多远。当行数未知时,如何将每一行转换为一列

参考文献。
参考

这次我很抱歉要自己动手:。。。以下查询接收HTML,将其转换为XML,定义列名,并在执行之前写入动态SQL

最终结果是:


SQL用于结构化数据。这需要知道列的数量、名称和数据类型。数据库引擎依赖于此。尝试执行您描述的操作会打破SQL范式。也许你在用错误的语言工作?或者,也许有更好的模式来解决您的实际问题?告诉我们你为什么要这样做,你将如何处理这些数据,也许我们可以指导你。但是,现在看来,你正试图迫使自己走上一条死胡同。虽然我完全同意sql可能不是处理数据的最佳方式,但这是绝对可行的。您需要搜索动态轴心或动态交叉表。它已经被询问和回答了数百次。事实上,你问题中的第二个链接详细说明了如何做到这一点。我想出来了。。即将发布解决方案
DECLARE @x XML,
 @limit int = 4,
 @ItemId NVARCHAR(10) = '11158',
 @cols AS NVARCHAR(MAX),
 @query  AS NVARCHAR(MAX)

-- get xml
SELECT @x = '<ul><li>Gas grill rotisserie</li><li>Fits the Genesis E-300 gas grill</li><li>Fits the Genesis S-300 gas grill</li><li>Includes a heavy-duty electric motor</li><li>Counterbalance for smooth turning and less motor wear</li></ul>'

-- convert rows to columns
select @cols = STUFF((SELECT distinct ',' + QUOTENAME(name) 
                    from
                    (
                      SELECT top (@limit)
                        bar.value('local-name(.)','VARCHAR(12)') + cast(row_number() over(order by bar.value('./.','VARCHAR(10)') asc) as varchar(10)) as name,  
                        bar.value('./.','VARCHAR(255)') as value 
                        FROM
                        @x.nodes('/ul/*') AS foo(bar) 
                    ) d
            FOR XML PATH(''), TYPE
            ).value('.', 'NVARCHAR(MAX)') 
        ,1,1,'')

-- create dynamic sql
set @query = '
            -- get xml
                DECLARE @x XML
                SELECT @x = ''<ul><li>Gas grill rotisserie</li><li>Fits the Genesis E-300 gas grill</li><li>Fits the Genesis S-300 gas grill</li><li>Includes a heavy-duty electric motor</li><li>Counterbalance for smooth turning and less motor wear</li></ul>''
            SELECT ' + @cols + ' 
             from 
             (
               SELECT
                bar.value(''local-name(.)'',''VARCHAR(12)'') + cast(row_number() over(order by bar.value(''./.'',''VARCHAR(10)'') asc) as varchar(10)) as name,  
                bar.value(''./.'',''VARCHAR(255)'') as value 
                FROM
                @x.nodes(''/ul/*'') AS foo(bar) 
            ) x
            pivot 
            (
                max(value)
                for name in (' + @cols + ')
            ) p '

execute sp_executesql @query;