在给文章加自定义标签时,需要在存储过程中对输入的字符串按照“,”字符分割成一个字符数组。但是Sql中没有实现字符串分组的Split方 法。因此就需要编写一个自定义的Split函数。我首先是使用表值函数的方法实现的字符串分组,但是在使用中感觉不是很方便。后来又在网上找到了一种使用 两个标量函数,其中一个函数首先返回分割后字符数组的长度,另一个函数依次返回每个分割出的字符串。然后使用循环依次获取分割的字符。
表值函数实现Split方法
1
Create
FUNCTION
[
dbo
]
.
[
SplitToTable
]
2
(
3
@SplitString
nvarchar
(
max
),
4
@Separator
nvarchar
(
10
)
=
'
'
5
)
6
RETURNS
@SplitStringsTable
TABLE
7
(
8
[
id
]
int
identity
(
1
,
1
),
9
[
value
]
nvarchar
(
max
)
10
)
11
AS
12
BEGIN
13
DECLARE
@CurrentIndex
int
;
14
DECLARE
@NextIndex
int
;
15
DECLARE
@ReturnText
nvarchar
(
max
);
16
SELECT
@CurrentIndex
=
1
;
17
WHILE
(
@CurrentIndex
<=
len
(
@SplitString
))
18
BEGIN
19
SELECT
@NextIndex
=
charindex
(
@Separator
,
@SplitString
,
@CurrentIndex
);
20
IF
(
@NextIndex
=
0
OR
@NextIndex
IS
NULL
)
21
SELECT
@NextIndex
=
len
(
@SplitString
)
+
1
;
22
SELECT
@ReturnText
=
substring
(
@SplitString
,
@CurrentIndex
,
@NextIndex
-
@CurrentIndex
);
23
INSERT
INTO
@SplitStringsTable
(
[
value
]
)
VALUES
(
@ReturnText
);
24
SELECT
@CurrentIndex
=
@NextIndex
+
1
;
25
END
26
RETURN
;
27
END
select * FROm dbo.SplitToTable('111,b2222,323232,32d,e,323232f,g3222', ',')
结果为
id value
----------- ---------------------------------------
1 111
2 b2222
3 323232
4 32d
5 e
6 323232f
7 g3222
(7 行受影响)
使用循环的方法
首先GetSplitLength函数返回分割后的字符数组的长度。
1
Create
function
[
dbo
]
.
[
GetSplitLength
]
2
(
3
@String
nvarchar
(
max
),
--
要分割的字符串
4
@Split
nvarchar
(
10
)
--
分隔符号
5
)
6
returns
int
7
as
8
begin
9
declare
@location
int
10
declare
@start
int
11
declare
@length
int
12
13
set
@String
=
ltrim
(
rtrim
(
@String
))
14
set
@location
=
charindex
(
@split
,
@String
)
15
set
@length
=
1
16
while
@location
<>
0
17
begin
18
set
@start
=
@location
+
1
19
set
@location
=
charindex
(
@split
,
@String
,
@start
)
20
set
@length
=
@length
+
1
21
end
22
return
@length
23
end
select dbo.GetSplitLength('111,b2222,323232,32d,e,323232f,g3222',',')
结果为7。
GetSplitOfIndex函数是按顺序分别获取分割后的字符串。
1
ALTER
function
[
dbo
]
.
[
GetSplitOfIndex
]
2
(
3
@String
nvarchar
(
max
),
--
要分割的字符串
4
@split
nvarchar
(
10
),
--
分隔符号
5
@index
int
--
取第几个元素
6
)
7
returns
nvarchar
(
1024
)
8
as
9
begin
10
declare
@location
int
11
declare
@start
int
12
declare
@next
int
13
declare
@seed
int
14
15
set
@String
=
ltrim
(
rtrim
(
@String
))
16
set
@start
=
1
17
set
@next
=
1
18
set
@seed
=
len
(
@split
)
19
20
set
@location
=
charindex
(
@split
,
@String
)
21
while
@location
<>
0
and
@index
>
@next
22
begin
23
set
@start
=
@location
+
@seed
24
set
@location
=
charindex
(
@split
,
@String
,
@start
)
25
set
@next
=
@next
+
1
26
end
27
if
@location
=
0
select
@location
=
len
(
@String
)
+
1
29
30
return
substring
(
@String
,
@start
,
@location
-
@start
)
31
end
select dbo.GetSplitOfIndex('111,b2222,323232,32d,e,323232f,g3222',',', 3)
结果323232。
1
DECLARE
@Tags
nvarchar
(
max
);
2
SELECT
@Tags
=
'
111,b2222,323232,32d,e,323232f,g3222
'
;
3
DECLARE
@Tag
nvarchar
(
1000
)
4
DECLARE
@next
int
;
5
set
@next
=
1
6
7
DECLARE
@Length
int
;
8
SELECT
@Length
=
dbo.GetSplitLength(
@Tags
,
'
,
'
)
9
10
while
@next
<=
@Length
11
begin
12
SET
@Tag
=
left
(dbo.GetSplitOfIndex(
@Tags
,
'
,
'
,
@next
),
16
);
13
print
@Tag
14
SET
@Next
=
@Next
+
1
;
15
END
结果为:
111
b2222
323232
32d
e
323232f
g3222