1. 程式人生 > >基於SQLSERVER實現:含分隔符字串資料轉換為多值IN列表的一種解決思路

基於SQLSERVER實現:含分隔符字串資料轉換為多值IN列表的一種解決思路


基於SQLSERVER實現:含分隔符字串資料轉換為多值IN列表
場景描述:資料表有一個字串,如 '3,1,2'
你希望在where 子句中使用上述字串,但是下面的SQL會由於EMPNO列是數值欄位而執行失敗。
select * from emp where empno in ('3,1,2')
原因是EMPNO是數值型別,而IN列表裡卻只有一個字串。你其實希望字串能夠被當作逗號分割的數值列表。
解決思路:
把字串打散,變成單個的EmpNo。
問:如何打散?
答:遍歷字串,解析字串,用資料庫函式把字串裡的每個元素轉換為有效的EMPNO。
實現:
1、遍歷字串:
select substring(csv.emps,iter.pos,len(csv.emps)) as c
from
(select ','+'3,1,2'+',' as emps) csv,
(select row_number() over(order by id) as pos from sysobjects)iter
where iter.pos<=len(csv.emps)
此處結果集:每行都比前一行少一個字元,是冗餘的全集,可從中提取所有的字串子項。
2、解析字串:
篩選以逗號開頭的行,然後在那一行找到下一個逗號,並留下兩個逗號之間的所有字元,這一步完成後,接著把要找到的字串轉化為數字。

select convert(int,substring(c,2,charindex(',',c,2)-2)) as empno from(
select substring(csv.emps,iter.pos,len(csv.emps)) as c
from
(select ','+'3,1,2'+',' as emps) csv,
(select row_number() over(order by id) as pos from sysobjects)iter
where iter.pos<=len(csv.emps)
)
至此,實現字串=>樹值列表的轉換。

完整例子:
select * from emp where empno in (
select convert(int,substring(c,2,charindex(',',c,2)-2)) as empno from(
select substring(csv.emps,iter.pos,len(csv.emps)) as c
from
(select ','+'3,1,2'+',' as emps) csv,
(select row_number() over(order by id) as pos from sysobjects)iter
where iter.pos<=len(csv.emps)
)
)
說明:
1、select row_number() over(order by id) as pos from sysobjects 用於生成位置的集合,語句可以替換。
前提是結果集為從1自增的集合且集合的行數>=字串長度即可
2、'3,1,2' 也可以替換為從某個表中select得到的字串。

&nbs