Xml存储在varchar列中。
其中一个节点就像
<PreviousItem>
<string>501</string>
<string>502</string>
<string>505</string>
</PreviousItem>
我需要将此节点元素作为comma delimited list (having issue with this part only)
以及此xml和表中的其他项。
SELECT
nId, cDescription,
,CAST(cSettings AS XML).value('data(/clsSettings/PreviousItem)[1]','nvarchar(max)') AS PreviousItem
,CAST(cSettings AS XML).value('data(/clsSettings/RegistrationType)[1]','nvarchar(50)') AS RegistrationType
FROM tblX
以上是我将PreviousItem作为501502505
。
我已尝试过关注,但我在Incorrect syntax near the keyword 'AS'
CAST(cSettings AS XML)
( SELECT
STUFF(( SELECT ',' + Prods.Prod.value('text()[1]','varchar(max)')
FROM CAST(cSettings AS XML).nodes('/clsSettings/PreviousItem') AS Prods ( Prod )
FOR XML PATH('')
), 1, 1, '')
) prods
答案 0 :(得分:1)
这是一种方法:
-- Sample Data
DECLARE @tblX TABLE (cID int identity, cSettings xml);
INSERT @tblX (cSettings)
VALUES
('<PreviousItem>
<string>501</string>
<string>502</string>
<string>505</string>
</PreviousItem>'),
('<PreviousItem>
<string>4433</string>
<string>5577</string>
</PreviousItem>');
-- Solution
SELECT
cID,
PreviousItem = STUFF
(
(
SELECT ',' + x.value('(text())[1]', 'varchar(500)')
FROM @tblX t
CROSS APPLY cSettings.nodes('/PreviousItem/string') x(x)
WHERE t.cID = tx.cId
FOR XML PATH('')
),1,1,''
)
FROM @tblX tx;
根据您的示例数据,您有一个存在于XML中的RegistrationType,您需要获取...这是我的第一个解决方案的调整版本。
-- Updated Sample Data with RegistrationType
DECLARE @tblX TABLE (cID int identity, cSettings xml);
INSERT @tblX (cSettings)
VALUES
('<PreviousItem>
<string>501</string>
<string>502</string>
<string>505</string>
</PreviousItem>
<RegistrationType>Type A</RegistrationType>
'),
('<PreviousItem>
<string>4433</string>
<string>5577</string>
</PreviousItem>
<RegistrationType>Type B</RegistrationType>
');
-- Solution which includes RegistrationType
SELECT
cID,
PreviousItem = STUFF
(
(
SELECT ',' + x.value('(text())[1]', 'varchar(500)')
FROM @tblX t
CROSS APPLY cSettings.nodes('/PreviousItem/string') x(x)
WHERE t.cID = tx.cId
FOR XML PATH('')
),1,1,''
),
RegistrationType = STUFF
(
(
SELECT ',' + x.value('(text())[1]', 'varchar(500)')
FROM @tblX t
CROSS APPLY cSettings.nodes('RegistrationType') x(x)
WHERE t.cID = tx.cId
FOR XML PATH('')
),1,1,''
)
FROM @tblX tx;
要获得更准确的解决方案,请提供一些DDL和耗材样本数据,我可以相应地修改我的解决方案。
更新:因为您的XML数据存储为文本,您需要调整原始解决方案,如下所示:
-- Updated Sample Data with RegistrationType
DECLARE @tblX TABLE (cID int identity, cSettings varchar(max));
INSERT @tblX (cSettings)
VALUES
('<PreviousItem>
<string>501</string>
<string>502</string>
<string>505</string>
</PreviousItem>
<RegistrationType>Type A</RegistrationType>
'),
('<PreviousItem>
<string>4433</string>
<string>5577</string>
</PreviousItem>
<RegistrationType>Type B</RegistrationType>
');
-- Solution which includes RegistrationType
SELECT
cID,
PreviousItem = STUFF
(
(
SELECT ',' + x.value('(text())[1]', 'varchar(500)')
FROM @tblX t
CROSS APPLY (VALUES (CAST(cSettings AS xml))) xx(xx)
CROSS APPLY xx.xx.nodes('/PreviousItem/string') x(x)
WHERE t.cID = tx.cId
FOR XML PATH('')
),1,1,''
),
RegistrationType = STUFF
(
(
SELECT ',' + x.value('(text())[1]', 'varchar(500)')
FROM @tblX t
CROSS APPLY (VALUES (CAST(cSettings AS xml))) xx(xx)
CROSS APPLY xx.xx.nodes('RegistrationType') x(x)
WHERE t.cID = tx.cId
FOR XML PATH('')
),1,1,''
)
FROM @tblX tx;
答案 1 :(得分:0)
因为你正在处理文本而不是XML,你可以使用一些基本的T-SQL和PatExclude8K来更有效地处理这个问题,如下所示:
-- Updated Sample Data with RegistrationType
DECLARE @tblX TABLE (cID int identity, cSettings varchar(max));
INSERT @tblX (cSettings)
VALUES
('<PreviousItem>
<string>501</string>
<string>502</string>
<string>505</string>
</PreviousItem>
<RegistrationType>Type A</RegistrationType>
'),
('<PreviousItem>
<string>4433</string>
<string>5577</string>
</PreviousItem>
<RegistrationType>Type B</RegistrationType>
');
-- Solution using PatExclude8K
SELECT
cID,
PreviousItem = SUBSTRING(NewString,1, LEN(NewString)-1),
RegistrationType = SUBSTRING
(
cSettings,
CHARINDEX('<RegistrationType>', cSettings)+18,
CHARINDEX('</RegistrationType>', cSettings) -
(CHARINDEX('<RegistrationType>', cSettings)+18)
)
FROM @tblX o
CROSS APPLY dbo.PatExclude8K(REPLACE(cSettings,'</string>',','), '[^0-9,]');