存储的Proc接收逗号sep的ID列表想要检索解码值的逗号sep列表

时间:2011-06-15 22:32:20

标签: sql xml sql-server-2008 tsql

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)

1 个答案:

答案 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,  '')