五维思考

学习要加,骄傲要减,机会要乘,懒惰要除。 http://www.5dthink.cn

  博客园 :: 首页 :: 博问 :: 闪存 :: 新随笔 :: 联系 :: 订阅 订阅 :: 管理 ::
declare @str nvarchar(50);
set @str='462,464,2';
select @str as '字符串'
select len(@str) as '字符长度'
select charindex(',',@str,1) as '第一个逗号的索引值'
select LEFT(@str,charindex(',',@str,1)-1) as '第一个值'
select SUBSTRING(@str,charindex(',',@str,1)+1,len(@str)) as '从第一逗号开始截取出后面的字符串'
select LEFT(SUBSTRING(@str,charindex(',',@str,1)+1,len(@str)),CHARINDEX(',',SUBSTRING(@str,charindex(',',@str,1)+1,len(@str)),1)-1) as '中间的值'
select SUBSTRING(SUBSTRING(@str,charindex(',',@str,1)+1,len(@str)),charindex(',',SUBSTRING(@str,charindex(',',@str,1)+1,len(@str)),1)+1,len(@str)) as '最后面的值' --从第二个逗号开始截取出其后的字符串

 


如果有一个字符串 eg: "sun,star,moon,clouds",想要在MS SQL中根据给定的分隔符','把这个字符串分解成各个元素[sun] [star] [moon] [clouds],如何实现呢?为此,创建一个Function,代码如下:

CREATE FUNCTION [dbo].[Split_StrByDelimiter](@String VARCHAR(8000), @Delimiter CHAR(1))       
  RETURNS @temptable TABLE (items VARCHAR(8000))       
AS       
    BEGIN       
     DECLARE @idx INT       
    DECLARE @slice VARCHAR(8000)       
 
    SELECT @idx = 1       
         IF len(@String)<1 OR @String IS NULL  RETURN       
 
      while @idx!= 0       
       BEGIN       
         SET @idx = charindex(@Delimiter,@String)       
         IF @idx!=0       
             SET @slice = LEFT(@String,@idx - 1)       
        ELSE       
             SET @slice = @String       
 
         IF(len(@slice)>0)  
            INSERT INTO @temptable(Items) VALUES(@slice)       
 
         SET @String = RIGHT(@String,len(@String) - @idx)       
          IF len(@String) = 0 break       
     END   
   RETURN       
 END

示例:如果输入 

SELECT * FROM dbo.Split_StrByDelimiter('sun,star,moon,clouds',',')
--结果:
sun
star
moon
clouds

在上面的代码做变形,返回有多少个元素

CREATE FUNCTION [dbo].[GetCount_Split_StrByDelimiter](@String VARCHAR(8000), @Delimiter CHAR(1))     
  RETURNS INT  
AS  
  BEGIN      
   DECLARE @temptable TABLE (items VARCHAR(8000))   
   DECLARE @SplitCount INT
     DECLARE @idx INT       
    DECLARE @slice VARCHAR(8000)       
 
    SELECT @idx = 1       
         IF len(@String)<1 OR @String IS NULL  RETURN  0   
 
      while @idx!= 0       
       BEGIN       
         SET @idx = charindex(@Delimiter,@String)       
         IF @idx!=0       
             SET @slice = LEFT(@String,@idx - 1)       
        ELSE       
             SET @slice = @String       
 
         IF(len(@slice)>0)  
            INSERT INTO @temptable(Items) VALUES(@slice)       
 
         SET @String = RIGHT(@String,len(@String) - @idx)       
          IF len(@String) = 0 break       
     END   
     SET  @SplitCount=(SELECT COUNT(*) FROM  @temptable)
   RETURN  @SplitCount
 END

示例

SELECT  dbo.GetCount_Split_StrByDelimiter('sun,star,moon,clouds',',')
--结果返回
4

 

--獲取被分隔符分割開來的字符串中參數的個數
CREATE function GetStrArrayLength
(
 
@str varchar(1024),  --要分割的字符串
 @split varchar(10)  --分隔符号
)
returns int
as
begin
 
declare @location int
 
declare @start int
 
declare @length int

 
set @str=ltrim(rtrim(@str))--剔除字符串的首尾空格
 
set @location=charindex(@split,@str)--第一個分隔符在字符串中的索引數字  例如'a1,b2,c3,d4'中第一個','的位置索引
 
set @length=1--字符串被分隔符分割開來的參數個數,這裡初始化為一個

 
while @location<>0 --如果字符串中還存在分隔符那麼該分隔符在字符串中的索引就不會為0,也就是不等於0
 begin
   
set @start=@location+1 --從第一個分隔符索引位置後的字符串中開始檢索,檢索的起始是第一個分隔符後的一位開始
   set @location=charindex(@split,@str,@start)
   
set @length=@length+1
 
end
 
return @length
end
---------------------------------------
--获得带分隔符的字符串中指定索引对应的间隔项
creat FUNCTION dbo.f_GetStr(
    
@s varchar(8000),      --包含多个数据项的字符串
    @pos int,             --要获取的数据项的位置
    @split varchar(10)     --数据分隔符
)RETURNS varchar(1000)
AS
BEGIN
    
IF @s IS NULL RETURN(NULL)
    
DECLARE @splitlen int
    
SELECT @splitlen=LEN(@split+'a')-2
    
WHILE @pos>1 AND CHARINDEX(@split,@s+@split)>0
        
SELECT @pos=@pos-1,
            
@s=STUFF(@s,1,CHARINDEX(@split,@s+@split)+@splitlen,'')
    
RETURN(ISNULL(LEFT(@s,CHARINDEX(@split,@s+@split)-1),''))
END
--------------------------------------------------------------
获得指定索引对应的间隔开来的单项字符数据
create function GetStr
(
 
@str varchar(1024),  --要分割的字符串
 @split varchar(10),  --分隔符号
 @index int --取第几个元素
)
returns varchar(1024)
as
begin
 
declare @location int
 
declare @start int
 
declare @next int
 
declare @seed int

 
set @str=ltrim(rtrim(@str))
 
set @start=1
 
set @next=1
 
set @seed=len(@split)
 
 
set @location=charindex(@split,@str)
 
while @location<>0 and @index>@next
 
begin
   
set @start=@location+@seed
   
set @location=charindex(@split,@str,@start)
   
set @next=@next+1
 
end
 
if @location =0 select @location =len(@str)+1  
 
return substring(@str,@start,@location-@start)
end

 


 --生成测试数据   
 Create table Tab([Col1] int,[COl2] nvarchar(5)) 
 Insert Tab 
 select 1,N'a,b,c' union all 
 select 2,N'd,e' union all 
 select 3,N'f' 
 Go 
  
--1. SQL2000用辅助表: 
 if object_id('Tempdb..#Num') is not null 
     drop table #Num 
 go 
 select top 100 ID=Identity(int,1,1) into #Num from syscolumns a,syscolumns b 
 Select  
     a.Col1,COl2=substring(a.Col2,b.ID,charindex(',',a.Col2+',',b.ID)-b.ID)  
 from  
     Tab a,#Num b 
 where 
     charindex(',',','+a.Col2,b.ID)=b.ID --也可用 substring(','+a.COl2,b.ID,1)=',' 
  
  
--2. SQL2005用Xml:   
 select  
     a.COl1,b.Col2 
 from  
     (select Col1,COl2=convert(xml,' <root> <v>'+replace(COl2,',',' </v> <v>')+' </v> </root>') from Tab)a 
 outer apply 
     (select Col2=C.v.value('.','nvarchar(100)') from a.COl2.nodes('/root/v')C(v))b 
  
  
--3. SQL2005用CTE:   
 ;with roy as  
 (select Col1,COl2=cast(left(Col2,charindex(',',Col2+',')-1) as nvarchar(100)),Split=cast(stuff(COl2+',',1,charindex(',',Col2+','),'') as nvarchar(100)) from Tab 
 union all 
 select Col1,COl2=cast(left(Split,charindex(',',Split)-1) as nvarchar(100)),Split= cast(stuff(Split,1,charindex(',',Split),'') as nvarchar(100)) from Roy where split>'' 
 ) 
 select COl1,COl2 from roy order by COl1 option (MAXRECURSION 0) 
  
--生成结果: 
 /* 
 Col1        COl2 
 ----------- ----- 
          a 
          b 
          c 
          d 
          e 
          f 
 */

 

posted on 2015-03-19 16:12  五维思考  阅读(448)  评论(0编辑  收藏  举报

QQ群:1. 全栈码农【346906288】2. VBA/VSTO【2660245】