• 根据分隔符,拆分字符串tsql


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

    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

     

     

  • 相关阅读:
    c#图像处理
    事件机制(复习)
    .net控件Control透明
    什么东西
    btn控件
    Tao 1.2.0图形框架发布
    java 泛型的类型擦除与桥方法
    来博客园的第一篇博文
    fastjson @JSONField
    java文件编译后,出现xx$1.class的原因
  • 原文地址:https://www.cnblogs.com/fly_zj/p/1803463.html
Copyright © 2020-2023  润新知