如果我是你的话,我两种方法都不会选择,不是方法不好,而是要花很多时间去琢磨,去理解,去写,我会选择一个通用的函数,在这个函数上稍微加工。 SQL Server数据库中拆分字符串函数的具体方法:CREATE FUNCTION uf_StrSplit '1.1.2.50','.' (@origStr varchar(7000), --待拆分的字符串 @Str varchar(100)) --拆分标记,如',' RETURNS @splittable table ( str_id varchar(4000) NOT NULL, --编号ID string varchar(2000) NOT NULL --拆分后的字符串 ) AS BEGIN declare @strlen int,@postion int,@start int,@sublen int, @TEMPstr varchar(200),@TEMPid int SELECT @strlen=LEN(@origStr),@start=1,@sublen=0,@postion=1, @TEMPstr='',@TEMPid=0 if(RIGHT(@origStr,1)<>@Str ) begin set @origStr = @origStr + @Str end WHILE((@postion<=@strlen) and (@postion !=0)) BEGIN IF(CHARINDEX(@Str,@origStr,@postion)!=0) BEGIN SET @sublen=CHARINDEX(@Str,@origStr,@postion)-@postion; END ELSE BEGIN SET @sublen=@strlen-@postion+1; END IF(@postion<=@strlen) BEGIN SET @TEMPid=@TEMPid+1; SET @TEMPstr=SUBSTRING(@origStr,@postion,@sublen); INSERT INTO @splittable(str_id,string) values(@TEMPid,@TEMPstr) IF(CHARINDEX(@Str,@origStr,@postion)!=0) BEGIN SET @postion=CHARINDEX(@Str,@origStr,@postion)+1 END ELSE BEGIN SET @postion=@postion+1 END END END RETURN END例如:select * from uf_StrSplit('1,1,2,50',',')输出结果:str_id string 1 1 2 1 3 2 4 50
2. --这个是递归查询 ;with tt as ( --这个是查询的开始部分 --下面之所以要cast as nvarchar(100)是因为, --查询开始部分和递归部分的字段的类型和长度,都不需要一致,否则会报错 select id,
--这个是逗号前的部分,也就是拆分出的第一个 [value]=cast(left([value],charindex(',',[value]+',')-1) as nvarchar(100)),
--剩余部分 Split=cast(stuff([value]+',',1,charindex(',',[value]+','),'') as nvarchar(100)) from tbunion all--这个是查询的递归部分 select id, --对上面的剩余部分,也就是split,再次递归的进行拆分 [value]=cast(left(Split,charindex(',',Split)-1) as nvarchar(100)),
--求剩余的部分 Split= cast(stuff(Split,1,charindex(',',Split),'') as nvarchar(100)) from tt where split>'' --如果剩余部分不是空 )select id,[value] from tt order by id option (MAXRECURSION 0) --递归次数不限制,由系统决定
1.OUTER APPLY这个是在2005以后才支持的,通过这个,能支持向outer apply中的查询,传入参数,然后把结果与主表进行关联。这个nodes是xml中的节点的意思,因为上面的数据组织成了xml,那么nodes('/root/v'),就是取/root/v这个节点下面的所有xml数据而value,就是取<v>和</v>之间的值,比如:<v>xxx</v>,那么就能取出xxx
SQL Server数据库中拆分字符串函数的具体方法:CREATE FUNCTION uf_StrSplit '1.1.2.50','.'
(@origStr varchar(7000), --待拆分的字符串
@Str varchar(100)) --拆分标记,如','
RETURNS @splittable table
(
str_id varchar(4000) NOT NULL, --编号ID
string varchar(2000) NOT NULL --拆分后的字符串
)
AS
BEGIN
declare @strlen int,@postion int,@start int,@sublen int,
@TEMPstr varchar(200),@TEMPid int
SELECT @strlen=LEN(@origStr),@start=1,@sublen=0,@postion=1,
@TEMPstr='',@TEMPid=0
if(RIGHT(@origStr,1)<>@Str )
begin
set @origStr = @origStr + @Str
end
WHILE((@postion<=@strlen) and (@postion !=0))
BEGIN
IF(CHARINDEX(@Str,@origStr,@postion)!=0)
BEGIN
SET @sublen=CHARINDEX(@Str,@origStr,@postion)-@postion;
END
ELSE
BEGIN
SET @sublen=@strlen-@postion+1;
END
IF(@postion<=@strlen)
BEGIN
SET @TEMPid=@TEMPid+1;
SET @TEMPstr=SUBSTRING(@origStr,@postion,@sublen);
INSERT INTO @splittable(str_id,string)
values(@TEMPid,@TEMPstr)
IF(CHARINDEX(@Str,@origStr,@postion)!=0)
BEGIN
SET @postion=CHARINDEX(@Str,@origStr,@postion)+1
END
ELSE
BEGIN
SET @postion=@postion+1
END
END
END
RETURN
END例如:select * from uf_StrSplit('1,1,2,50',',')输出结果:str_id string
1 1
2 1
3 2
4 50
2.
--这个是递归查询
;with tt as
(
--这个是查询的开始部分
--下面之所以要cast as nvarchar(100)是因为,
--查询开始部分和递归部分的字段的类型和长度,都不需要一致,否则会报错
select id,
--这个是逗号前的部分,也就是拆分出的第一个
[value]=cast(left([value],charindex(',',[value]+',')-1) as nvarchar(100)),
--剩余部分
Split=cast(stuff([value]+',',1,charindex(',',[value]+','),'') as nvarchar(100))
from tbunion all--这个是查询的递归部分
select id, --对上面的剩余部分,也就是split,再次递归的进行拆分
[value]=cast(left(Split,charindex(',',Split)-1) as nvarchar(100)),
--求剩余的部分
Split= cast(stuff(Split,1,charindex(',',Split),'') as nvarchar(100))
from tt
where split>'' --如果剩余部分不是空
)select id,[value]
from tt
order by id
option (MAXRECURSION 0) --递归次数不限制,由系统决定
那个N换成随意的都可以,不知道这个是什么意思可以,比如换成ww(xx),那么前面也得换成ww.xx.values...