现在的位置: 首页 > 综合 > 正文

根据分隔符,拆分字符串t-sql

2012年04月30日 ⁄ 综合 ⁄ 共 2233字 ⁄ 字号 评论关闭

常遇到根据分隔符来拆分字符串的,总结三种方法:

1.使用union all 方法

代码

--使用union all 方法
--
思路是组装成select语句的联合[SELECT '张三' union all select '李四' union all select '王五']
DECLARE @str NVARCHAR(MAX);
SET @str='张三,李四,王五';
SET @str='SELECT '+''''+ REPLACE(@str,',',''' union all select ''')+'''';
PRINT @str;
EXEC( @str);

 

2.使用临时表

 

代码

--使用临时表
--
思路是拼凑成[,张三,李四,王五,]字符串,找到每个[,]字符的位置,再通过substring函数依次截取
DECLARE @str NVARCHAR(MAX);
SET @str=N','+N'张三,李四,王五'+N',';

--创建临时表
SELECT TOP(50) IDENTITY(INT,1,1) AS col1
INTO #demo1
FROM sys.objects o,sys.objects o2

--创建字符[,]位置序列表#demo2
SELECT ROW_NUMBER() OVER (ORDER BY col1 ASC) AS ident,
col1
INTO #demo2 FROM #demo1
WHERE col1=CHARINDEX(',',@str,col1);

--根据[,]字符位置依次截取字符串
SELECT SUBSTRING(@str,d3.col1+1,d2.col1-d3.col1-1) FROM #demo2 d2
INNER JOIN #demo2 d3
ON d2.ident=d3.ident+1;
DROP TABLE #demo1,#demo2;
GO

 

3.使用CTE方法解决,思路与使用临时表相同

 

代码

--把上面的TSQL语句使用CTE联合起来使用
DECLARE @str NVARCHAR(MAX);
SET @str=N','+N'张三,李四,王五'+N','
;
WITH #demo1 AS
(
SELECT TOP(50) ROW_NUMBER() OVER (ORDER BY [object_id] ASC) AS col1
FROM sys.objects
ORDER BY col1 ASC
),
#demo2
AS
(
SELECT ROW_NUMBER() OVER (ORDER BY col1 ASC) AS ident,
col1
FROM #demo1
WHERE col1=CHARINDEX(',',@str,col1)
)
SELECT SUBSTRING(@str,d3.col1+1,d2.col1-d3.col1-1) FROM #demo2 d2
INNER JOIN #demo2 d3
ON d2.ident=d3.ident+1;

 

总结:字符串拆分无非就这几招:临时表法,动态TSQL,循环法,游标法,公用表达式(CTE)法等总有一种最优的

 

 

2.使用辅助表和临时表

 

--使用辅助表,临时表法
--使用master..spt_values使用辅助的number列,从-2048

IF OBJECT_ID('tempdb..#t') IS NOT NULL 
DROP TABLE tempdb..#t;

CREATE TABLE  #t (col INT IDENTITY(1,1),number INT);
DECLARE @str NVARCHAR(MAX);
SET @str='张三,李四,王五';
SET @str=','+@str+',';

--创建临时表,表变量不能使用别名
INSERT  INTO #t (number)  SELECT sv.number FROM [master].dbo.spt_values sv 
WHERE TYPE='p' 
AND number= CHARINDEX(',',@str,sv.number);

SELECT SUBSTRING(@str,number+1,name_length-1) AS col FROM 
(
	SELECT t1.number, t2.number-t1.number AS name_length  FROM #t t1 INNER JOIN #t t2
	ON t1.col+1=t2.col
) AS tmp

3.使用循环截取法(网上摘录)
 
-- 分拆字符串- 循环截取法
CREATE FUNCTION dbo.f_splitSTR(
	@s   varchar(8000),   --待分拆的字符串
	@split varchar(10)     --数据分隔符
)RETURNS @re TABLE(
		col varchar(100))
AS
BEGIN
	DECLARE 
		@splitlen int

	-- 取分隔符的长度, 在分隔符后面加一个字符是为了避免分隔符以空格结束时, 取不到正确的长度
	SET @splitlen = LEN(@split + 'a') - 2
	-- 如果待分拆的字符串中存在数据分隔符, 则循环取出每个数据项
	WHILE CHARINDEX(@split, @s)>0
	BEGIN
		-- 取第一个数据分隔符前的数据项
		INSERT @re VALUES(LEFT(@s, CHARINDEX(@split, @s) - 1))
		
		-- 将已经取出的第一个数据项和数据分隔符从待分拆的字符串中去掉
		SET @s = STUFF(@s, 1, CHARINDEX(@split, @s) + @splitlen, '')
	END
	
	-- 保存最后一个数据项(最后一个数据项后面没有数据分隔符, 故在前面的循环中不会被处理)
	INSERT @re VALUES(@s)
	RETURN
END
GO

 

 

 

抱歉!评论已关闭.