【问题标题】:Retrive data from xml and get the format从xml中检索数据并获取格式
【发布时间】:2018-09-19 14:39:11
【问题描述】:

您好,我将数据存储在列名中的表(cmsContentXml)中作为 xml

<Ingredients id="1515" parentID="1062" level="3" creatorID="1" sortOrder="0" createDate="2014-07-23T07:54:58" updateDate="2014-09-06T17:14:45" nodeName="Ingredients" urlName="ingredients" path="-1,1055,1062,1515" isDoc="" nodeType="1514" creatorName="Admin" writerName="ndopuch" writerID="2" template="0" nodeTypeAlias="Ingredients">
  <quickList>
     <![CDATA[1526,1530,1531,1536,1539,1549,1560,1564,1565,1567,1569,1572,1586,1587,1592,1594,1600,1601,1602,1651,1658,1660,1682,1696,1693,1715,1716,1717,1771,1799,1615,1669,1676,1685,1697,1730,1746,1757,1768,1779,1778,1785,1789,1794,1803,1805,1813,1826,1830,1843,1852,1858,1866,1880,1917,1913,1920,1927,1931,1936,1956,1959,1872]]>
  </quickList>
</Ingredients>

我想从路径部分获取如下数据“-1,1055,1062,1515”,而 1526,1530,1531 来自 xml 节点的快速列表

-1,1055,1062,1515,1526
-1,1055,1062,1515,1530
-1,1055,1062,1515,1531
-1,1055,1062,1515,1536
.
.
.
-1,1055,1062,1515,1872

我已尝试将数据检索为

SELECT
[xml].value('(/Ingredients/quickList)', 'nvarchar(max)') as data
FROM [cmsContentXml]  where [nodeId]=1515

但给出错误为

Cannot find either column "xml" or the user-defined function or aggregate "xml.value", or the name is ambiguous.

示例数据格式

CREATE TABLE #cmsContentXml(
    nodeid [int],
    [xml] [nvarchar](max) NOT NULL    
)

INSERT INTO #cmsContentXml VALUES (1515,'<Ingredients id="1515" parentID="1062" level="3" creatorID="1" sortOrder="0" createDate="2014-07-23T07:54:58" updateDate="2014-09-06T17:14:45" nodeName="Ingredients" urlName="ingredients" path="-1,1055,1062,1515" isDoc="" nodeType="1514" creatorName="Admin" writerName="ndopuch" writerID="2" template="0" nodeTypeAlias="Ingredients">
    <quickList><![CDATA[1526,1530,1531,1536,1539,1549,1560,1564,1565,1567,1569,1572,1586,1587,1592,1594,1600,1601,1602,1651,1658,1660,1682,1696,1693,1715,1716,1717,1771,1799,1615,1669,1676,1685,1697,1730,1746,1757,1768,1779,1778,1785,1789,1794,1803,1805,1813,1826,1830,1843,1852,1858,1866,1880,1917,1913,1920,1927,1931,1936,1956,1959,1872]]></quickList>
</Ingredients>
');

请帮我检索数据

 Data_Column
-1,1055,1062,1515,1526
-1,1055,1062,1515,1530
-1,1055,1062,1515,1531
-1,1055,1062,1515,1536
.
.
.
-1,1055,1062,1515,1872

【问题讨论】:

  • Here 是一个很好的起点。
  • @SeanLange 好的更新它
  • 您正在使用 2008 版本的精确...对吗?

标签: sql-server xml sql-server-2008


【解决方案1】:

这应该可行:

DECLARE @xml xml ='<Ingredients id="1515" parentID="1062" level="3" creatorID="1" sortOrder="0" createDate="2014-07-23T07:54:58" updateDate="2014-09-06T17:14:45" nodeName="Ingredients" urlName="ingredients" path="-1,1055,1062,1515" isDoc="" nodeType="1514" creatorName="Admin" writerName="ndopuch" writerID="2" template="0" nodeTypeAlias="Ingredients">
  <quickList>
     <![CDATA[1526,1530,1531,1536,1539,1549,1560,1564,1565,1567,1569,1572,1586,1587,1592,1594,1600,1601,1602,1651,1658,1660,1682,1696,1693,1715,1716,1717,1771,1799,1615,1669,1676,1685,1697,1730,1746,1757,1768,1779,1778,1785,1789,1794,1803,1805,1813,1826,1830,1843,1852,1858,1866,1880,1917,1913,1920,1927,1931,1936,1956,1959,1872]]>
  </quickList>
</Ingredients>'

SELECT Path+','+Num FROM (
    SELECT Path.value('.', 'nvarchar(MAX)')
    FROM @xml.nodes('Ingredients/@path') X(Path)
) T1(Path)
CROSS JOIN (
    SELECT REPLACE(REPLACE(A.value('.','nvarchar(MAX)'),' ',''),char(10),'') FROM
    (
        SELECT CAST('<a>'+REPLACE(quickList.value('.','nvarchar(MAX)'),',','</a><a>')+'</a>' as xml) X
        FROM @xml.nodes('Ingredients/quickList') X(quickList)
    ) qlXml
    CROSS APPLY X.nodes('a') T(A)
) T2(Num)

【讨论】:

    【解决方案2】:

    您面临的第一个问题是您处理nvarchar 就像一个xml。您必须将其转换为 xml 才能执行任何操作。

    你遇到的另一个问题是你查询:你必须提到你用text()获取节点内部内容的sql server

    以下问题是您必须要求使用[1] 获取xml 的第一个元素,否则sql server 将无法知道您要如何处理它可能获得的列表。

    然后您需要拆分从 xml 中获得的字符串。自 sql server 2016 起,您拥有 STRING_SPLIT 函数。最后,cross apply 将所有拆分后的值分布在您的行上。

    with parsedAsXml as (
        select 
            c.nodeId as NodeId, 
            cast(c.[xml] as xml) as [xml]
        FROM 
            #cmsContentXml as c
    ),
    sub as (
        SELECT 
            c.nodeId as NodeId, 
            c.[xml].value('(/Ingredients/quickList/text())[1]', 'nvarchar(max)') as QuickList,
            c.[xml].value('(/Ingredients/@path)[1]', 'nvarchar(max)') as path
        FROM 
            parsedAsXml as c
    )
    SELECT 
        s.[path] + ',' + ql.[Value]
    FROM 
        sub as s
        cross apply STRING_SPLIT(s.QuickList, ',') as ql
    where 
        s.NodeId=1515;
    

    如果你用的是sql server 2008,你必须自己做一个split函数(这里叫splitstring,可耻地抄自T-SQL split string)。

    CREATE FUNCTION dbo.splitstring (@stringToSplit VARCHAR(MAX), @separator VARCHAR(50) )
    RETURNS
     @returnList TABLE ([Value] [nvarchar] (500))
    AS
    BEGIN
    
     DECLARE @name NVARCHAR(255)
     DECLARE @pos INT
    
     WHILE CHARINDEX(@separator, @stringToSplit) > 0
     BEGIN
      SELECT @pos  = CHARINDEX(@separator, @stringToSplit)  
      SELECT @name = SUBSTRING(@stringToSplit, 1, @pos-1)
    
      INSERT INTO @returnList 
      SELECT @name
    
      SELECT @stringToSplit = SUBSTRING(@stringToSplit, @pos+1, LEN(@stringToSplit)-@pos)
     END
    
     INSERT INTO @returnList
     SELECT @stringToSplit
    
     RETURN
    END
    GO
    

    【讨论】:

      猜你喜欢
      • 2017-11-23
      • 2018-12-10
      • 1970-01-01
      • 2018-10-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-07-23
      相关资源
      最近更新 更多