嗨,我将数据存储在表(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节点的quickList
-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
答案 0 :(得分:0)
这应该有效:
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)
答案 1 :(得分:0)
您面临的第一个问题是您像处理xml这样处理nvarchar
的事实。要执行任何操作,必须将其转换为xml。
您遇到的另一个问题是查询:您必须提到使用text()
以下问题是您必须要求使用[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,则必须创建自己的分割函数(在这里称为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