查询存储过程中的结果集.(顺便贴:一行折多行的方法)
一般的,在数据库中会存放以"," 分隔的字符串,在 SQL 端不太好操作,须一些函数的配合,下面依次列举.
一.取指定的字符串在其中的索引.
create function [dbo].[GetIndexStringSimple](@SourceSql varchar(4000), @StrSeprate varchar(10),@index int )
returns varchar(4000)
as
begin
declare @curIndex int
declare @i int
select @i = 0 ,@curIndex =1 ;
while @curIndex>=1
begin
set @curIndex=charindex(@StrSeprate,@SourceSql)
set @i = @i + 1 ;
if ( @index = @i )
begin
if ( @curIndex = 0 )
return @SourceSql ;
else
return substring(@SourceSql,0,@curIndex) ;
end
set @SourceSql=substring(@SourceSql,@curIndex+1,len(@SourceSql)-@curIndex)
end
return null;
end
returns varchar(4000)
as
begin
declare @curIndex int
declare @i int
select @i = 0 ,@curIndex =1 ;
while @curIndex>=1
begin
set @curIndex=charindex(@StrSeprate,@SourceSql)
set @i = @i + 1 ;
if ( @index = @i )
begin
if ( @curIndex = 0 )
return @SourceSql ;
else
return substring(@SourceSql,0,@curIndex) ;
end
set @SourceSql=substring(@SourceSql,@curIndex+1,len(@SourceSql)-@curIndex)
end
return null;
end
如果是第一个参数是 Text 类型的话,再包一层:
CREATE function [dbo].[GetIndexString](@SourceSql text,@index int )
returns varchar(8000)
as
begin
if ( @index = 0 ) return null ;
declare @TheSourceSql varchar(8000)
set @TheSourceSql = cast(@SourceSql as varchar(8000));
declare @Len int ;
set @Len = datalength(@SourceSql);
declare @perCount int ;
declare @curIndex int ;
declare @sectEndIndex int ;
declare @retVal varchar(8000) ;
declare @curVal varchar(8000) ;
declare @readLen int ;
set @perCount = 7990
set @readLen = 0
if @Len <=@perCount
begin
return dbo.GetIndexStringSimple(@TheSourceSql,',',@index) ;
end
set @curIndex = 1 ;set @sectEndIndex = 0 ;
while ( @curIndex ) < @Len
begin
set @TheSourceSql = SUBSTRING(@SourceSql , @curIndex , @perCount )
set @sectEndIndex = len(@TheSourceSql);
while @sectEndIndex >0
begin
if ( SUBSTRING(@TheSourceSql,@sectEndIndex,1) = ',' or @Len < @curIndex + @sectEndIndex )
begin
if ( SUBSTRING(@TheSourceSql,@sectEndIndex,1) = ',' )
begin
set @TheSourceSql = SUBSTRING(@TheSourceSql ,1 , @sectEndIndex -1 )
end else begin
set @TheSourceSql = SUBSTRING(@TheSourceSql ,1 , @sectEndIndex )
end
set @curIndex = @curIndex + @sectEndIndex ;
set @curVal = dbo.GetIndexStringSimple(@TheSourceSql,',',@index) ;
if ( @curVal is not null )
begin
return @curVal ;
end else begin
set @index = @index + dbo.GetStringIndexSimple(@TheSourceSql,',',',')
if ( @index < 1 ) return null;
break;
end;
end
else begin
set @sectEndIndex = @sectEndIndex -1 ;
end
end
end
return @retVal ;
end
returns varchar(8000)
as
begin
if ( @index = 0 ) return null ;
declare @TheSourceSql varchar(8000)
set @TheSourceSql = cast(@SourceSql as varchar(8000));
declare @Len int ;
set @Len = datalength(@SourceSql);
declare @perCount int ;
declare @curIndex int ;
declare @sectEndIndex int ;
declare @retVal varchar(8000) ;
declare @curVal varchar(8000) ;
declare @readLen int ;
set @perCount = 7990
set @readLen = 0
if @Len <=@perCount
begin
return dbo.GetIndexStringSimple(@TheSourceSql,',',@index) ;
end
set @curIndex = 1 ;set @sectEndIndex = 0 ;
while ( @curIndex ) < @Len
begin
set @TheSourceSql = SUBSTRING(@SourceSql , @curIndex , @perCount )
set @sectEndIndex = len(@TheSourceSql);
while @sectEndIndex >0
begin
if ( SUBSTRING(@TheSourceSql,@sectEndIndex,1) = ',' or @Len < @curIndex + @sectEndIndex )
begin
if ( SUBSTRING(@TheSourceSql,@sectEndIndex,1) = ',' )
begin
set @TheSourceSql = SUBSTRING(@TheSourceSql ,1 , @sectEndIndex -1 )
end else begin
set @TheSourceSql = SUBSTRING(@TheSourceSql ,1 , @sectEndIndex )
end
set @curIndex = @curIndex + @sectEndIndex ;
set @curVal = dbo.GetIndexStringSimple(@TheSourceSql,',',@index) ;
if ( @curVal is not null )
begin
return @curVal ;
end else begin
set @index = @index + dbo.GetStringIndexSimple(@TheSourceSql,',',',')
if ( @index < 1 ) return null;
break;
end;
end
else begin
set @sectEndIndex = @sectEndIndex -1 ;
end
end
end
return @retVal ;
end
二.取指定索引的字符串.
--返回索引从1开始的位置,如果找不到,返回 搜索串的个数 的负值
CREATE function [dbo].[GetStringIndexSimple](@SourceSql varchar(8000), @StrSeprate varchar(10),@strFind varchar(4000) )
returns int
as
begin
if ( @strFind = @SourceSql ) return 1 ;
declare @curIndex int ;
declare @retVal int ;
declare @ier int ;
set @SourceSql = ',' + @SourceSql + ',' ;
set @curIndex = charindex(',' +@strFind + ',',@SourceSql) ;
set @ier = 1 ;
set @retVal = 0 ;
if ( @curIndex =0 )
begin
set @ier = -1 ;
set @retVal = -1 ;
set @curIndex = len(@SourceSql) ;
end
set @SourceSql = left ( @SourceSql , @curIndex -1 ) ;
while @curIndex >=1
begin
set @curIndex = charindex(@StrSeprate,@SourceSql) ;
set @retVal = @retVal + 1 ;
if ( @curIndex <= 0 ) goto ret ;
set @SourceSql = right ( @SourceSql ,len(@SourceSql) - @curIndex) ;
end
ret:
return ( @retVal) * @ier;
end
CREATE function [dbo].[GetStringIndexSimple](@SourceSql varchar(8000), @StrSeprate varchar(10),@strFind varchar(4000) )
returns int
as
begin
if ( @strFind = @SourceSql ) return 1 ;
declare @curIndex int ;
declare @retVal int ;
declare @ier int ;
set @SourceSql = ',' + @SourceSql + ',' ;
set @curIndex = charindex(',' +@strFind + ',',@SourceSql) ;
set @ier = 1 ;
set @retVal = 0 ;
if ( @curIndex =0 )
begin
set @ier = -1 ;
set @retVal = -1 ;
set @curIndex = len(@SourceSql) ;
end
set @SourceSql = left ( @SourceSql , @curIndex -1 ) ;
while @curIndex >=1
begin
set @curIndex = charindex(@StrSeprate,@SourceSql) ;
set @retVal = @retVal + 1 ;
if ( @curIndex <= 0 ) goto ret ;
set @SourceSql = right ( @SourceSql ,len(@SourceSql) - @curIndex) ;
end
ret:
return ( @retVal) * @ier;
end
如果第一个参数是 Text 类型的话:
CREATE function [dbo].[GetStringIndex](@SourceSql text,@strFind varchar(4000) )
returns int
as
begin
declare @TheSourceSql varchar(8000)
set @TheSourceSql = cast(@SourceSql as varchar(8000));
declare @Len int ;
set @Len = datalength(@SourceSql);
if ( @Len = len(@strFind) and @TheSourceSql = @strFind ) return 1 ;
declare @perCount int ;
declare @curIndex int ;
declare @sectEndIndex int ;
declare @retVal int ;
declare @curVal int ;
declare @readLen int ;
set @perCount = 7990 set @retVal = 0 set @readLen = 0
if @Len <=@perCount
begin
return dbo.GetStringIndexSimple(@TheSourceSql,',',@strFind) ;
end
set @curIndex = 1 ;set @sectEndIndex = 0 ;
while ( @curIndex ) < @Len
begin
set @TheSourceSql = SUBSTRING(@SourceSql , @curIndex , @perCount )
set @sectEndIndex = len(@TheSourceSql);
while @sectEndIndex >0
begin
if ( SUBSTRING(@TheSourceSql,@sectEndIndex,1) = ',' or @Len < @curIndex + @sectEndIndex )
begin
if ( SUBSTRING(@TheSourceSql,@sectEndIndex,1) = ',' )
begin
set @TheSourceSql = SUBSTRING(@TheSourceSql ,1 , @sectEndIndex -1 )
end else begin
set @TheSourceSql = SUBSTRING(@TheSourceSql ,1 , @sectEndIndex )
end
set @curIndex = @curIndex + @sectEndIndex ;
set @curVal = dbo.GetStringIndexSimple(@TheSourceSql,',',@strFind) ;
if ( @curVal > 0 )
begin
return cast( @curVal - @retVal as varchar(30))
end else begin
set @retVal = @retVal + @curVal;
--set @TheSourceSql = SUBSTRING(@SourceSql , @sectEndIndex +1, @perCount )
--return @TheSourceSql
break;
end
end
else begin
set @sectEndIndex = @sectEndIndex -1 ;
end
end
end
return @retVal ;
end
returns int
as
begin
declare @TheSourceSql varchar(8000)
set @TheSourceSql = cast(@SourceSql as varchar(8000));
declare @Len int ;
set @Len = datalength(@SourceSql);
if ( @Len = len(@strFind) and @TheSourceSql = @strFind ) return 1 ;
declare @perCount int ;
declare @curIndex int ;
declare @sectEndIndex int ;
declare @retVal int ;
declare @curVal int ;
declare @readLen int ;
set @perCount = 7990 set @retVal = 0 set @readLen = 0
if @Len <=@perCount
begin
return dbo.GetStringIndexSimple(@TheSourceSql,',',@strFind) ;
end
set @curIndex = 1 ;set @sectEndIndex = 0 ;
while ( @curIndex ) < @Len
begin
set @TheSourceSql = SUBSTRING(@SourceSql , @curIndex , @perCount )
set @sectEndIndex = len(@TheSourceSql);
while @sectEndIndex >0
begin
if ( SUBSTRING(@TheSourceSql,@sectEndIndex,1) = ',' or @Len < @curIndex + @sectEndIndex )
begin
if ( SUBSTRING(@TheSourceSql,@sectEndIndex,1) = ',' )
begin
set @TheSourceSql = SUBSTRING(@TheSourceSql ,1 , @sectEndIndex -1 )
end else begin
set @TheSourceSql = SUBSTRING(@TheSourceSql ,1 , @sectEndIndex )
end
set @curIndex = @curIndex + @sectEndIndex ;
set @curVal = dbo.GetStringIndexSimple(@TheSourceSql,',',@strFind) ;
if ( @curVal > 0 )
begin
return cast( @curVal - @retVal as varchar(30))
end else begin
set @retVal = @retVal + @curVal;
--set @TheSourceSql = SUBSTRING(@SourceSql , @sectEndIndex +1, @perCount )
--return @TheSourceSql
break;
end
end
else begin
set @sectEndIndex = @sectEndIndex -1 ;
end
end
end
return @retVal ;
end
三.把一行折分多行的存储过程.
CREATE Proc [dbo].[P_SplitSimple](@S varchar(8000) )
as
declare @Rec table(Value varchar(2000))
begin
declare @i as int
declare @TempVale varchar(2000)
set @i=charindex(',',@s)
while @i>0 begin
set @TempVale=left(@S,@i-1)
insert @Rec values(@TempVale)
set @S=right(@S,len(@S)-@i)
set @i=charindex(',',@S)
end
insert @Rec values(@s)
select * from @Rec
end
as
declare @Rec table(Value varchar(2000))
begin
declare @i as int
declare @TempVale varchar(2000)
set @i=charindex(',',@s)
while @i>0 begin
set @TempVale=left(@S,@i-1)
insert @Rec values(@TempVale)
set @S=right(@S,len(@S)-@i)
set @i=charindex(',',@S)
end
insert @Rec values(@s)
select * from @Rec
end
调用方法:
![](/Images/OutliningIndicators/None.gif)
![](/Images/OutliningIndicators/None.gif)
![](/Images/OutliningIndicators/None.gif)
![](/Images/OutliningIndicators/None.gif)
![](/Images/OutliningIndicators/None.gif)
![](/Images/OutliningIndicators/None.gif)
![](/Images/OutliningIndicators/None.gif)
四. 多行合成一行的方法:
declare @tab table (id int )
declare @i int
declare @str varchar(300)
select @i = 0 ,@str = '['
while @i < 20 begin
insert into @tab
select @i
select @i = @i + 1
end
select @str = @str + cast(id as varchar) + ',' from @tab
select @str =substring(@str,1,len(@str) -1 ) + ']'
select @str
declare @i int
declare @str varchar(300)
select @i = 0 ,@str = '['
while @i < 20 begin
insert into @tab
select @i
select @i = @i + 1
end
select @str = @str + cast(id as varchar) + ',' from @tab
select @str =substring(@str,1,len(@str) -1 ) + ']'
select @str
SQL 操作字符串还是比较弱, 不支持 正则表达式.
![]() |
作者:NewSea 出处:http://newsea.cnblogs.com/
QQ,MSN:iamnewsea@hotmail.com 如无特别标记说明,均为NewSea原创,版权私有,翻载必纠。欢迎交流,转载,但要在页面明显位置给出原文连接。谢谢。 |