--各种字符串分函数if exists (select * from dbo.sysobjects where id = object_id(N'[dbo].[f_splitSTR]') and xtype in (N'FN', N'IF', N'TF'))
drop function [dbo].[f_splitSTR]
GO--3.2.1 循环截取法
CREATE FUNCTION f_splitSTR(
@s   varchar(8000),   --待分拆的字符串
@split varchar(10)     --数据分隔符
)RETURNS @re TABLE(col varchar(100))
AS
BEGIN
DECLARE @splitlen int
SET @splitlen=LEN(@split+'a')-2
WHILE CHARINDEX(@split,@s)>0
BEGIN
INSERT @re VALUES(LEFT(@s,CHARINDEX(@split,@s)-1))
SET @s=STUFF(@s,1,CHARINDEX(@split,@s)+@splitlen,'')
END
INSERT @re VALUES(@s)
RETURN
END
GO
/*==============================================*/if exists (select * from dbo.sysobjects where id = object_id(N'[dbo].[f_splitSTR]') and xtype in (N'FN', N'IF', N'TF'))
drop function [dbo].[f_splitSTR]
GO--3.2.3.1 使用临时性分拆辅助表法
CREATE FUNCTION f_splitSTR(
@s   varchar(8000),  --待分拆的字符串
@split varchar(10)     --数据分隔符
)RETURNS @re TABLE(col varchar(100))
AS
BEGIN
--创建分拆处理的辅助表(用户定义函数中只能操作表变量)
DECLARE @t TABLE(ID int IDENTITY,b bit)
INSERT @t(b) SELECT TOP 8000 0 FROM syscolumns a,syscolumns b INSERT @re SELECT SUBSTRING(@s,ID,CHARINDEX(@split,@s+@split,ID)-ID)
FROM @t
WHERE ID<=LEN(@s+'a') 
AND CHARINDEX(@split,@split+@s,ID)=ID
RETURN
END
GO/*==============================================*/if exists (select * from dbo.sysobjects where id = object_id(N'[dbo].[f_splitSTR]') and xtype in (N'FN', N'IF', N'TF'))
drop function [dbo].[f_splitSTR]
GOif exists (select * from dbo.sysobjects where id = object_id(N'[dbo].[tb_splitSTR]') and objectproperty(id,N'IsUserTable')=1)
drop table [dbo].[tb_splitSTR]
GO--3.2.3.2 使用永久性分拆辅助表法
--字符串分拆辅助表
SELECT TOP 8000 ID=IDENTITY(int,1,1) INTO dbo.tb_splitSTR
FROM syscolumns a,syscolumns b
GO--字符串分拆处理函数
CREATE FUNCTION f_splitSTR(
@s     varchar(8000),  --待分拆的字符串
@split  varchar(10)     --数据分隔符
)RETURNS TABLE
AS
RETURN(
SELECT col=CAST(SUBSTRING(@s,ID,CHARINDEX(@split,@s+@split,ID)-ID) as varchar(100))
FROM tb_splitSTR
WHERE ID<=LEN(@s+'a') 
AND CHARINDEX(@split,@split+@s,ID)=ID)
GO
/*==============================================*/if exists (select * from dbo.sysobjects where id = object_id(N'[dbo].[f_splitSTR]') and xtype in (N'FN', N'IF', N'TF'))
drop function [dbo].[f_splitSTR]
GO--3.2.5 将数据项按数字与非数字再次拆份
CREATE FUNCTION f_splitSTR(
@s   varchar(8000),    --待分拆的字符串
@split varchar(10)     --数据分隔符
)RETURNS @re TABLE(No varchar(100),Value varchar(20))
AS
BEGIN
--创建分拆处理的辅助表(用户定义函数中只能操作表变量)
DECLARE @t TABLE(ID int IDENTITY,b bit)
INSERT @t(b) SELECT TOP 8000 0 FROM syscolumns a,syscolumns b INSERT @re 
SELECT No=REVERSE(STUFF(col,1,PATINDEX('%[^-^.^0-9]%',col+'a')-1,'')),
Value=REVERSE(LEFT(col,PATINDEX('%[^-^.^0-9]%',col+'a')-1))
FROM(
SELECT col=REVERSE(SUBSTRING(@s,ID,CHARINDEX(@split,@s+@split,ID)-ID))
FROM @t
WHERE ID<=LEN(@s+'a') 
AND CHARINDEX(@split,@split+@s,ID)=ID)a
RETURN
END
GO
/*==============================================*/if exists (select * from dbo.sysobjects where id = object_id(N'[dbo].[f_splitSTR]') and xtype in (N'FN', N'IF', N'TF'))
drop function [dbo].[f_splitSTR]
GO--3.2.6 分拆短信数据
CREATE FUNCTION f_splitSTR(@s varchar(8000))
RETURNS @re TABLE(split varchar(10),value varchar(100))
AS
BEGIN
DECLARE @splits TABLE(split varchar(10),splitlen as LEN(split))
INSERT @splits(split)
SELECT 'AC' UNION ALL
SELECT 'BC' UNION ALL
SELECT 'CC' UNION ALL
SELECT 'DC'
DECLARE @pos1 int,@pos2 int,@split varchar(10),@splitlen int
SELECT TOP 1 
@pos1=1,@split=split,@splitlen=splitlen
FROM @splits
WHERE @s LIKE split+'%'
WHILE @pos1>0
BEGIN
SELECT TOP 1
@pos2=CHARINDEX(split,@s,@splitlen+1)
FROM @splits
WHERE CHARINDEX(split,@s,@splitlen+1)>0
ORDER BY CHARINDEX(split,@s,@splitlen+1)
IF @@ROWCOUNT=0
BEGIN
INSERT @re VALUES(@split,STUFF(@s,1,@splitlen,''))
RETURN
END
ELSE
BEGIN
INSERT @re VALUES(@split,SUBSTRING(@s,@splitlen+1,@pos2-@splitlen-1))
SELECT TOP 1 
@pos1=1,@split=split,@splitlen=splitlen,@s=STUFF(@s,1,@pos2-1,'')
FROM @splits
WHERE STUFF(@s,1,@pos2-1,'') LIKE split+'%'
END
END
RETURN
END
GO

解决方案 »

  1.   

    create table tb(col varchar(100))
    insert tb
    select '1*2*3*4' 
    declare @col varchar(100)
    set @col=(select col from tb)exec('select '+@col)drop table tb
      

  2.   

    --合并分拆表
    /******************************************************************************************************************************************************
    合并分拆表数据整理人:中国风(Roy)日期:2008.06.06
    ******************************************************************************************************************************************************/--> --> (Roy)生成測試數據
     
    if not object_id('Tab') is null
        drop table Tab
    Go
    Create table Tab([Col1] int,[Col2] nvarchar(1))
    Insert Tab
    select 1,N'a' union all
    select 1,N'b' union all
    select 1,N'c' union all
    select 2,N'd' union all
    select 2,N'e' union all
    select 3,N'f'
    Go合并表:SQL2000用函数:go
    if object_id('F_Str') is not null
        drop function F_Str
    go
    create function F_Str(@Col1 int)
    returns nvarchar(100)
    as
    begin
        declare @S nvarchar(100)
        select @S=isnull(@S+',','')+Col2 from Tab where Col1=@Col1
        return @S
    end
    go
    Select distinct Col1,Col2=dbo.F_Str(Col1) from TabgoSQL2005用XML:方法1:select 
        a.Col1,Col2=stuff(b.Col2.value('/R[1]','nvarchar(max)'),1,1,'')
    from 
        (select distinct COl1 from Tab) a
    Cross apply
        (select COl2=(select N','+Col2 from Tab where Col1=a.COl1 For XML PATH(''), ROOT('R'), TYPE))b方法2:select 
        a.Col1,COl2=replace(b.Col2.value('/Tab[1]','nvarchar(max)'),char(44)+char(32),char(44))
    from 
        (select distinct COl1 from Tab) a
    cross apply
        (select Col2=(select COl2 from Tab  where COl1=a.COl1 FOR XML AUTO, TYPE)
                    .query('<Tab>
                    {for $i in /Tab[position()<last()]/@COl2 return concat(string($i),",")}
                    {concat("",string(/Tab[last()]/@COl2))}
                    </Tab>')
                    )bSQL05用CTE:;with roy as(select Col1,Col2,row=row_number()over(partition by COl1 order by COl1) from Tab)
    ,Roy2 as
    (select COl1,cast(COl2 as nvarchar(100))COl2,row from Roy where row=1 
    union all 
    select a.Col1,cast(b.COl2+','+a.COl2 as nvarchar(100)),a.row from Roy a join Roy2 b on a.COl1=b.COl1 and a.row=b.row+1)
    select Col1,Col2 from Roy2 a where row=(select max(row) from roy where Col1=a.COl1) order by Col1 option (MAXRECURSION 0)
    生成结果:
    /*
    Col1        COl2
    ----------- ------------
    1           a,b,c
    2           d,e
    3           f(3 行受影响)
    */
    拆分表:--> --> (Roy)生成測試數據
     
    if not object_id('Tab') is null
        drop table Tab
    Go
    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'
    GoSQL2000用辅助表:
    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)=','
    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
    SQL05用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
    ----------- -----
    1           a
    1           b
    1           c
    2           d
    2           e
    3           f
    */
      

  3.   

    create function dbo.fn_split 

    @inputstr varchar(8000), 
    @seprator varchar(10) 

    returns @temp table (a varchar(200)) 
    as 
    begin 
    declare @i int 
    set @inputstr = rtrim(ltrim(@inputstr)) 
    set @i = charindex(@seprator, @inputstr) 
    while @i >= 1 
    begin 
    insert @temp values(left(@inputstr, @i - 1)) 
    set @inputstr = substring(@inputstr, @i + 1, len(@inputstr) - @i) 
    set @i = charindex(@seprator, @inputstr) 
    end 
    if @inputstr <> '\' 
    insert @temp values(@inputstr) 
    return 
    end 
    go 
    --调用 
    declare @s varchar(1000) 
    set @s='1,2,3,4,5,6,7,8,55' 
    select * from dbo.fn_split(@s,',') 
    drop function dbo.fn_split 
      

  4.   

    写自定义函数去分析表达式。
    或者调用js或vb的eval来实现。exec动态语句适用性不大,因为表里并不是一条记录,更不可能循环去调用exec性能太差。http://topic.csdn.net/u/20090108/09/d646cd38-7e8b-484e-9db6-380bc70bb3c7.html
      

  5.   

    楼上的,你们sql都是手写的么?有没有辅助的工具呢?
      

  6.   

    create table tb(col varchar(100),col2 int,id int identity(1,1))
    insert tb
    select '1*2*3*4',0 union
    select '2*3*4*5',0declare @sql varchar(8000)
    set @sql=''
    select @sql=@sql+' update tb set col2='+col+' where id='+rtrim(id)
    from tbexec(@sql)select col2 from tbdrop table tb
    /*
    col2        
    ----------- 
    24
    120
    */
      

  7.   

    用EXCEL也可以实现。比如按*分列,再对各列使用函数。
      

  8.   

    create table Tb_UinonConfig(prim1 real,arithmetic varchar(50))
    insert into Tb_UinonConfig select 100,'+20.5×15÷13.1'
    insert into Tb_UinonConfig select 80 ,'÷2.5×100+23.0'
    insert into Tb_UinonConfig select -80,'+100+(23.0×6)'
    gocreate function f_calc(
    @str varchar(1000)--要计算的表达式
    )returns sql_variant
    as
    begin
    declare @re sql_variantdeclare @err int,@src varchar(255),@desc varchar(255)
    declare @obj intexec @err=sp_oacreate 'MSScriptControl.ScriptControl',@obj out
    if @err<>0 goto lb_errexec @err=sp_oasetproperty @obj,'Language','vbscript'
    if @err<>0 goto lb_errexec @err=sp_oamethod @obj,'Eval',@re out,@str
    if @err=0 return(@re)lb_err:
    exec sp_oageterrorinfo NULL, @src out, @desc out 
    declare @errb varbinary(4),@s varchar(20)
    set @errb=cast(@err as varbinary(4))
    exec master..xp_varbintohexstr @errb,@s out
    return('错误号: '+@s+char(13)+'错误源: '+@src+char(13)+'错误描述: '+@desc)
    end
    goselect prim1,arithmetic,
    dbo.f_calc(cast(prim1 as varchar)+replace(replace(arithmetic,'×','*'),'÷','/')) as col from Tb_UinonConfig
    drop function f_calc
    drop table Tb_UinonConfig
    /*autoid      col         
    ----------- ----------- 
    1           1
    2           1
    3           2
    4           2*/
      

  9.   

    set nocount on
    if object_id('tempdb..#T')is not null drop table #T
    go
    create table #T(field varchar(100)) 
    ----------- 
    insert #T select 1*2*3*4 
    insert #T select 1*2*23*14 
    insert #T select 1*32*13*4 
    go
    if object_id('dbo.fn_split')is not null drop function dbo.fn_split
    go
    create function dbo.fn_split 

    @inputstr varchar(8000), 
    @seprator varchar(10) 

    returns decimal(10,2) 
    as 
    begin 
    declare @i int 
    declare @t decimal(10,2)
    set   @t=1   
    declare @temp table(a int)
    set @inputstr = rtrim(ltrim(@inputstr)) 
    set @i = charindex(@seprator, @inputstr) 
    while @i >= 1 
    begin 
    insert @temp values(left(@inputstr, @i - 1)) 
    set @inputstr = substring(@inputstr, @i + 1, len(@inputstr) - @i) 
    set @i = charindex(@seprator, @inputstr) 
    end 
    if @inputstr <> '\' 
    insert @temp values(@inputstr) 
    select   @t=@t   *   a   from   @temp   
    return @t
    end 
    go 
    select dbo.fn_split(field,'*') from #T 
    /*------------ 
    24.00
    644.00
    1664.00*/