循环读取 Sql 服务器中的逗号分隔字符串
Read comma separated string in Sql server in loop
我有这样的 nvarchar 数据:
'20030,20031,20033,20034,20065,20045,20044'
我想通过拆分成数组读取所有这些或者在拆分过程中一个一个读取并做进一步处理。
我试过这个good article但是做不到。
试试这个 article 使用函数读取逗号分隔值和 return table
CREATE FUNCTION dbo.Split(@String nvarchar(4000), @Delimiter char(1))
RETURNS @Results TABLE (Items nvarchar(4000))
AS
BEGIN
DECLARE @INDEX INT
DECLARE @SLICE nvarchar(4000)
-- HAVE TO SET TO 1 SO IT DOESNT EQUAL Z
-- ERO FIRST TIME IN LOOP
SELECT @INDEX = 1
WHILE @INDEX !=0
BEGIN
-- GET THE INDEX OF THE FIRST OCCURENCE OF THE SPLIT CHARACTER
SELECT @INDEX = CHARINDEX(@Delimiter,@STRING)
-- NOW PUSH EVERYTHING TO THE LEFT OF IT INTO THE SLICE VARIABLE
IF @INDEX !=0
SELECT @SLICE = LEFT(@STRING,@INDEX - 1)
ELSE
SELECT @SLICE = @STRING
-- PUT THE ITEM INTO THE RESULTS SET
INSERT INTO @Results(Items) VALUES(@SLICE)
-- CHOP THE ITEM REMOVED OFF THE MAIN STRING
SELECT @STRING = RIGHT(@STRING,LEN(@STRING) - @INDEX)
-- BREAK OUT IF WE ARE DONE
IF LEN(@STRING) = 0 BREAK
END
RETURN
END
只需调用存储过程中的函数或调用如下函数:
SELECT items FROM [dbo].[Split] ('20030,20031,20033,20034,20065,20045,20044', ',')
一点都不难。最好使用递归来解决
create table #Testdata2(Data varchar(max))
insert #Testdata2 select '20030,20031,20033,20034,20065,20045,20044'
;with tmp(DataItem, Data) as (
select LEFT(Data, CHARINDEX(',',Data+',')-1),
STUFF(Data, 1, CHARINDEX(',',Data+','), '')
from #Testdata2
union all
select LEFT(Data, CHARINDEX(',',Data+',')-1),
STUFF(Data, 1, CHARINDEX(',',Data+','), '')
from tmp
where Data > ''
)
select DataItem
from tmp
OPTION (maxrecursion 0)
输出:
(select)
Data
----------------
20030,20031,20033,20034,20065,20045,20044
(query)
DataItem
----------------
20030
20031
20033
20034
20065
20045
20044
另一种使用 String Split And 的方法 Xml
DECLARE @string nvarchar(max)='20030,20031,20033,20034,20065,20045,20044'
DECLARE @Table AS TABLE (String nvarchar(max))
INSERT INTO @Table
SELECT @string
SELECT Row_NUmber ()OVER(ORDER BY (SELECT 1) )AS Seq, Split.a.value('.', 'VARCHAR(1000)') AS String
FROM (
SELECT CAST('<S>' + REPLACE(String, ',', '</S><S>') + '</S>' AS XML) AS String
FROM @Table
) AS A
CROSS APPLY String.nodes('/S') AS Split(a)
以上代码可以合并到函数中return拆分字符串
CREATE FUNCTION dbo.udf_Split (
@String NVARCHAR(4000)
,@Delimiter CHAR(1)
)
RETURNS @Results TABLE (Items NVARCHAR(4000))
AS
BEGIN
DECLARE @Table AS TABLE (String NVARCHAR(max))
INSERT INTO @Table
SELECT @String
INSERT INTO @Results
SELECT Split.a.value('.', 'VARCHAR(1000)') AS String
FROM (
SELECT CAST('<S>' + REPLACE(String, @Delimiter, '</S><S>') + '</S>' AS XML) AS String
FROM @Table
) AS A
CROSS APPLY String.nodes('/S') AS Split(a)
RETURN
END
SELECT ROW_NUMBER()OVER(ORDER BY (SELECT 1))AS Seq,
* FROM dbo.udf_Split('20030,20031,20033,20034,20065,20045,20044',',')
结果
Seq String
----------
1 20030
2 20031
3 20033
4 20034
5 20065
6 20045
7 20044
我有这样的 nvarchar 数据:
'20030,20031,20033,20034,20065,20045,20044'
我想通过拆分成数组读取所有这些或者在拆分过程中一个一个读取并做进一步处理。
我试过这个good article但是做不到。
试试这个 article 使用函数读取逗号分隔值和 return table
CREATE FUNCTION dbo.Split(@String nvarchar(4000), @Delimiter char(1))
RETURNS @Results TABLE (Items nvarchar(4000))
AS
BEGIN
DECLARE @INDEX INT
DECLARE @SLICE nvarchar(4000)
-- HAVE TO SET TO 1 SO IT DOESNT EQUAL Z
-- ERO FIRST TIME IN LOOP
SELECT @INDEX = 1
WHILE @INDEX !=0
BEGIN
-- GET THE INDEX OF THE FIRST OCCURENCE OF THE SPLIT CHARACTER
SELECT @INDEX = CHARINDEX(@Delimiter,@STRING)
-- NOW PUSH EVERYTHING TO THE LEFT OF IT INTO THE SLICE VARIABLE
IF @INDEX !=0
SELECT @SLICE = LEFT(@STRING,@INDEX - 1)
ELSE
SELECT @SLICE = @STRING
-- PUT THE ITEM INTO THE RESULTS SET
INSERT INTO @Results(Items) VALUES(@SLICE)
-- CHOP THE ITEM REMOVED OFF THE MAIN STRING
SELECT @STRING = RIGHT(@STRING,LEN(@STRING) - @INDEX)
-- BREAK OUT IF WE ARE DONE
IF LEN(@STRING) = 0 BREAK
END
RETURN
END
只需调用存储过程中的函数或调用如下函数:
SELECT items FROM [dbo].[Split] ('20030,20031,20033,20034,20065,20045,20044', ',')
一点都不难。最好使用递归来解决
create table #Testdata2(Data varchar(max))
insert #Testdata2 select '20030,20031,20033,20034,20065,20045,20044'
;with tmp(DataItem, Data) as (
select LEFT(Data, CHARINDEX(',',Data+',')-1),
STUFF(Data, 1, CHARINDEX(',',Data+','), '')
from #Testdata2
union all
select LEFT(Data, CHARINDEX(',',Data+',')-1),
STUFF(Data, 1, CHARINDEX(',',Data+','), '')
from tmp
where Data > ''
)
select DataItem
from tmp
OPTION (maxrecursion 0)
输出:
(select)
Data
----------------
20030,20031,20033,20034,20065,20045,20044
(query)
DataItem
----------------
20030
20031
20033
20034
20065
20045
20044
另一种使用 String Split And 的方法 Xml
DECLARE @string nvarchar(max)='20030,20031,20033,20034,20065,20045,20044'
DECLARE @Table AS TABLE (String nvarchar(max))
INSERT INTO @Table
SELECT @string
SELECT Row_NUmber ()OVER(ORDER BY (SELECT 1) )AS Seq, Split.a.value('.', 'VARCHAR(1000)') AS String
FROM (
SELECT CAST('<S>' + REPLACE(String, ',', '</S><S>') + '</S>' AS XML) AS String
FROM @Table
) AS A
CROSS APPLY String.nodes('/S') AS Split(a)
以上代码可以合并到函数中return拆分字符串
CREATE FUNCTION dbo.udf_Split (
@String NVARCHAR(4000)
,@Delimiter CHAR(1)
)
RETURNS @Results TABLE (Items NVARCHAR(4000))
AS
BEGIN
DECLARE @Table AS TABLE (String NVARCHAR(max))
INSERT INTO @Table
SELECT @String
INSERT INTO @Results
SELECT Split.a.value('.', 'VARCHAR(1000)') AS String
FROM (
SELECT CAST('<S>' + REPLACE(String, @Delimiter, '</S><S>') + '</S>' AS XML) AS String
FROM @Table
) AS A
CROSS APPLY String.nodes('/S') AS Split(a)
RETURN
END
SELECT ROW_NUMBER()OVER(ORDER BY (SELECT 1))AS Seq,
* FROM dbo.udf_Split('20030,20031,20033,20034,20065,20045,20044',',')
结果
Seq String
----------
1 20030
2 20031
3 20033
4 20034
5 20065
6 20045
7 20044