DECLARE @x varchar(250), @xx xml
如果我在SP中输入的dept ID列表如下所示:
set @x = '3, 9, 10, 12, 14'
我可以轻松地将其转换为XML并像这样查询:
set @xx = '<xml><e>' + REPLACE(@x,', ','</e><e>') + '</e></xml>'
select @xx
返回:
<xml><e>3</e><e>9</e><e>10</e><e>12</e><e>14</e></xml>
和
select @xx.query('for $d in /xml/e return data($d)')
返回:
3 9 10 12 14
使用XML路径当我手头知道DeptID时,我可以手动获取逗号分隔的部门名称列表
select SUBSTRING((SELECT (', '+DeptName) from vDepartments where DeptID in (3, 9, 10, 12, 14) for xml path('')), 3, 1000)
但是,我认为我应该可以从上面的XML中做到这一点:
select SUBSTRING((SELECT (', '+DeptName) from vDepartments where DeptID in @xx.query('for $d in /xml/e return string($d)') for xml path('')), 3, 1000)
答案 0 :(得分:0)
我会将参数中的id放在表变量中,并在针对vDepartment的连接中使用它
-- Comma separated parameter
declare @x varchar(250)
set @x = '3, 9, 10, 12, 14'
-- Convert to xml
declare @xx xml
set @xx = '<xml><e>' + REPLACE(@x,', ','</e><e>') + '</e></xml>'
-- Table variable to hold ID's from parameter
declare @T table(ID int)
-- Get ID's from xml
insert into @T (ID)
select N.value('.', 'int')
from @xx.nodes('xml/e') as T(N)
-- Use the table in a inner join.
select stuff(
(select ', '+DeptName
from vDepartments as D
inner join @T as T
on D.DeptID = T.ID
for xml path(''), type).value('.', 'varchar(max)'), 1, 2, '')
如果您使用.value
提取以逗号分隔的部门列表,则系统名称中的<>&'"
会毫不费力。
修改1
使用递归CTE获取ID而不是转换为XML的版本。一站式查询。
;with cte(ID, Rest) as
(
select cast(left(@x, charindex(',', @x+',')-1) as int),
stuff(@x, 1, charindex(',', @x+','), '')+','
where len(@x) > 0
union all
select cast(left(Rest, charindex(',', Rest)-1) as int),
stuff(Rest, 1, charindex(',', Rest), '')
from cte
where len(Rest) > 1
)
select stuff(
(select ', '+DeptName
from vDepartments as D
inner join cte as T
on D.DeptID = T.ID
for xml path(''), type).value('.', 'varchar(max)'), 1, 2, '')