Tsql SQL Server 2008 T-SQL UDF Split()裁剪

Tsql SQL Server 2008 T-SQL UDF Split()裁剪,tsql,sql-server-2008,user-defined-functions,Tsql,Sql Server 2008,User Defined Functions,我使用的是SQLSER2008,有一个只有一列数据的大表。数据是一个随机字符串,几乎没有一致性。Eample:姓名账户445560010020056893010445478008 AFD 369。我一直在使用stackoverflow用户建议的拆分函数。它工作得很好,但是该函数将拆分的字符串分配到一列中。我需要一行单独的列。当前结果是1 COL,值为Name、Account、445566、,。。。但我要找的结果是col1名称,col2帐户,col3 445566,。。。 如果有人能提供一些关于如

我使用的是SQLSER2008,有一个只有一列数据的大表。数据是一个随机字符串,几乎没有一致性。Eample:姓名账户445560010020056893010445478008 AFD 369。我一直在使用stackoverflow用户建议的拆分函数。它工作得很好,但是该函数将拆分的字符串分配到一列中。我需要一行单独的列。当前结果是1 COL,值为Name、Account、445566、,。。。但我要找的结果是col1名称,col2帐户,col3 445566,。。。 如果有人能提供一些关于如何定制此脚本或其使用以获得所需结果的见解,将不胜感激

CREATE FUNCTION [dbo].[Split] 
(    
 @String varchar(max) 
,@Delimiter char 
) 
RETURNS @Results table 
( 
 Ordinal int 
,StringValue varchar(max) 
) 
as 
begin 

set @String = isnull(@String,'') 
set @Delimiter = isnull(@Delimiter,'') 

declare 
 @TempString varchar(max) = @String 
,@Ordinal int = 0 
,@CharIndex int = 0 

set @CharIndex = charindex(@Delimiter, @TempString) 
while @CharIndex != 0 begin      
    set @Ordinal += 1        
    insert @Results values 
    ( 
     @Ordinal 
    ,substring(@TempString, 0, @CharIndex) 
    )        
    set @TempString = substring(@TempString, @CharIndex + 1, len(@TempString) - @CharIndex)      
    set @CharIndex = charindex(@Delimiter, @TempString) 
end 

if @TempString != '' begin 
    set @Ordinal += 1  
    insert @Results values 
    ( 
     @Ordinal 
    ,@TempString 
    ) 
end 

return 
end 

--The usage:
SELECT    
* 
FROM    
mytable M    
CROSS APPLY    
[dbo].[Split] (M.TheColumn, ' ') S
Where rtrim(s.StringValue) != '' 

您可以尝试使用枢轴


如果您知道字符串中有6列,您可以使用如下所示的拆分函数,当然可以将该函数修改为所需的任意列数。函数不能返回动态列数

create function dbo.Split6(@String varchar(max), @Delimiter char(1)) 
returns table as return
(
  select
    substring(T.Col, 1, S1.Pos-1) as Col1,
    substring(T.Col, S1.Pos+1, S2.Pos-S1.Pos-1) as Col2,
    substring(T.Col, S2.Pos+1, S3.Pos-S2.Pos-1) as Col3,
    substring(T.Col, S3.Pos+1, S4.Pos-S3.Pos-1) as Col4,
    substring(T.Col, S4.Pos+1, S5.Pos-S4.Pos-1) as Col5,
    substring(T.Col, S5.Pos+1, S6.Pos-S5.Pos-1) as Col6
  from (select @String+replicate(@Delimiter, 6)) as T(Col)
    cross apply (select charindex(@Delimiter, T.Col, 1)) as S1(Pos)
    cross apply (select charindex(@Delimiter, T.Col, S1.Pos+1)) as S2(Pos)
    cross apply (select charindex(@Delimiter, T.Col, S2.Pos+1)) as S3(Pos)
    cross apply (select charindex(@Delimiter, T.Col, S3.Pos+1)) as S4(Pos)
    cross apply (select charindex(@Delimiter, T.Col, S4.Pos+1)) as S5(Pos)
    cross apply (select charindex(@Delimiter, T.Col, S5.Pos+1)) as S6(Pos)
)
测试:

结果:

Col1  Col2     Col3    Col4                       Col5  Col6
----  -------  ------  -------------------------  ----  ----
Name  Account  445566  0010020056893010445478008  AFD   369

1     2             
1              3            

顺便说一句,该函数是从@antisanity借用的,它在表上的用法来自@gbn。谢谢大家!你想达到什么目标?该数据是在维护还是在导入?输出表的宽度是变化的还是静态的?我正在反向工程一个旧的平面文件批处理。数据由包含120个字符的字符串组成。表格宽度将是静态列数。我的目标是将字符串拆分为一行列,不仅仅是一列包含所有数据,而是9或10列。这将一次影响大约10000行数据。再次感谢antisanity提供的任何帮助!我应该能够在使用脚本后透视表列,但我一直在寻找一种解决方法。我的想法是,如果你可以拆分一个字符串并将数据插入一列,也许你可以将其分配到脚本中的几个不同列。我知道这听起来好像我没有使用最明显的工具,但我对性能有一半的关注(数据透视一个超过100000行的表,希望不会两次碰到cpu,这仍然需要一段时间,再加上这个过程会发生多次)一半的人只是想看看是否可以做到。我不太精通T-Sql,所以我想我应该问问专家。这看起来不错。我最终会找到我需要多少列,所以我认为这会很好地工作!谢谢!
Col1  Col2     Col3    Col4                       Col5  Col6
----  -------  ------  -------------------------  ----  ----
Name  Account  445566  0010020056893010445478008  AFD   369

1     2             
1              3