SQL分割逗號的函數和用法

      在程序中我們可能經常會遇到這種情況,比如要取一個listbox裏面的選擇項,得到的結果可能是string ID="id1,id2,id3,id4",然後我們要把這些ID插入到數據庫中,同時每個id對應的是要插入一條記錄。實現的方法有很多,但是如果我們通過下面這個函數(RecurrentSplit)就能簡單的達到上述效果。RecurrentSplit的使用也非常簡單。

例如:

select row_number()over(order by indexno desc) as seq ,* from recurrentsplit('1,2,3,4,5,',',',0,0)

這樣我們就會分成5條記錄,因爲我的要求是一個listbox中item[i]其中最小的說明他的排序在最前頭,同時排序是但SEQ的降序排列。所以在這個查詢中我用row_number()over(order by indexno desc) as seq得出了他的順序號

如下

seq indexno   SplitName

1        4          5
2        3          4
3        2          3
4        1          2
5        0          1

然後就是對這個結果進行操作咯

 --設置選擇商品爲推薦並按傳入的降序將商品推薦排序   
update zp_auction_mst
         set ishot=1,hotseq = b.seq
        from zp_auction_mst a,
         (select row_number()over(order by indexno desc) as seq ,* from recurrentsplit(@AuctionID,',',0,0)) as b
         where a.auctionid= b.splitName

 

 

搞定,就是這麼簡單了。。。。

 

CREATE FUNCTION [dbo].[RecurrentSplit]
(
@nvStr nvarchar(2000)  --需要分割字符串
,@vSeparte varchar(50)  --分割字符串
,@iIsHaveSeparte int   --是否顯示字符串
,@iIsBefore int    --是否是後面的分割符(分割字符分割的順序)
)
RETURNS @Split table
(
IndexNo int default(0)   --流水號
,SplitName nvarchar(1000)  --分割後字符串
)
AS
BEGIN
 if(charindex(@vSeparte,@nvStr)<=0) --處理在整個字符串裏都沒有要分割,也就是字符串本身
 begin
  insert into @Split(SplitName) values(@nvStr)
  return
 end
 declare @iSeparteLen int
 ,@iEndHave int --最後幾個字符串是否是分割字符
 ,@iStartHave int --前面幾個字符串是否是分割字符
 select @iSeparteLen=len(@vSeparte)
 ,@iStartHave=0
 ,@iEndHave=0
 ,@iIsHaveSeparte=case when @iIsHaveSeparte is null --默認值
  then 0
  else @iIsHaveSeparte
  end
 ,@iIsBefore=case when @iIsBefore is null --默認值
  then 0
  else @iIsBefore
  end
 if(@iIsBefore=1) --只有在處理前面字符串分割時才用
 begin
  if(left(@nvStr,@iSeparteLen)<>@vSeparte)--處理前面幾個分割字符一定是分割字符,不是就加
  begin
   select @nvStr=@vSeparte+@nvStr
   ,@iStartHave=1
  end
 end
 if(right(@nvStr,@iSeparteLen)<>@vSeparte)--處理最後幾個分割字符一定是分割字符,不是就加
 begin
  select @nvStr=@nvStr+@vSeparte
  ,@iEndHave=1
 end; --分號一定不能少,因爲用了with,是用公用表達式,在其前面一定要加;
 
 with CharCET(CharStr,StrLen,IndexNo)
 as
 (
  select substring(@nvStr,0
  ,case when @iIsBefore=0 then charindex(@vSeparte,@nvStr)+@iSeparteLen
  else charindex(@vSeparte,@nvStr,charindex(@vSeparte,@nvStr)+@iSeparteLen) end
  ) CharStr
  ,case when @iIsBefore=0 then charindex(@vSeparte,@nvStr)
  else charindex(@vSeparte,@nvStr,charindex(@vSeparte,@nvStr)+@iSeparteLen) end StrLen
  ,0 IndexNo  --第一次初始化
  union all
  select substring(@nvStr
  ,case when @iIsBefore=0 then StrLen+@iSeparteLen
  else StrLen end
  ,charindex(@vSeparte,@nvStr,StrLen+@iSeparteLen)-StrLen) CharStr
  ,charindex(@vSeparte,@nvStr,StrLen+@iSeparteLen) StrLen
  ,IndexNo+1 IndexNo --進行遞歸分割字符串
  from CharCET
  where StrLen<len(@nvStr)-@iSeparteLen --處理遞歸結束語句,也就是不要讓其生成無限弟歸下去
 )
 insert into @Split(IndexNo,SplitName)
 select IndexNo,case when @iIsHaveSeparte=0
  then replace(CharStr,@vSeparte,'')
  else CharStr
  end CharStr
 from CharCET
 option(maxrecursion 0)
 
 if(@iIsHaveSeparte=1) --是否顯示分割字符串
 begin
  update @Split --處理前面的分割字符串
  set SplitName=case when @iStartHave=1
   then replace(SplitName,@vSeparte,'')
   else SplitName
   end
  where IndexNo = 0

  update @Split --處理後面的分割字符串
  set SplitName=case when @iEndHave=1
   then replace(SplitName,@vSeparte,'')
   else SplitName
   end
  where IndexNo = (select Max(IndexNo) from @Split)
 end
 RETURN
END

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章