zoukankan      html  css  js  c++  java
  • SQL Server ->> Move characters in string N position(s) forward/backward based on ASCII table(根据ASCII表的排列顺序将字符串内的数值往前或者后移N个位)

    去年无聊的时候想到想玩一下根据ASCII表的排列顺序将字符串内的数值往前或者后移N个位,顺便看一下是T-SQL性能好还是用C#写CLR函数处理得快。结果是在50万行以下其实两者差距很小,当然这是在我的笔记本上测试的结果(I5双核四线程+8G内存+5600转的机械硬盘)。在100万行以上的时候用T-SQL基于集合的方式就体现出优势了,用了大概1分多钟就处理完100万行,而CLR用了4分多钟还没处理完。这里贴上当时的T-SQL代码。

    if OBJECT_ID('tempdb..#tt') is not null
        drop table #tt
        
    if OBJECT_ID('tempdb..#t') is not null
        drop table #t
    
    if OBJECT_ID('tempdb..#ttt') is not null
        drop table #ttt
        
    if OBJECT_ID('tempdb..#tttt') is not null
        drop table #tttt
    
    select dbo.tblNumbers.id, abs(CHECKSUM(NEWID()))%62 as fld1, 
               abs(CHECKSUM(NEWID()))%62 as fld2,
               abs(CHECKSUM(NEWID()))%62 as fld3,
               abs(CHECKSUM(NEWID()))%62 as fld4,
               abs(CHECKSUM(NEWID()))%62 as fld5,
               abs(CHECKSUM(NEWID()))%62 as fld6,
               abs(CHECKSUM(NEWID()))%62 as fld7,
               abs(CHECKSUM(NEWID()))%62 as fld8,
               abs(CHECKSUM(NEWID()))%62 as fld9, 
               abs(CHECKSUM(NEWID()))%62 as fld10,
               abs(CHECKSUM(NEWID()))%62 as fld11,
               abs(CHECKSUM(NEWID()))%62 as fld12,
               abs(CHECKSUM(NEWID()))%62 as fld13,
               abs(CHECKSUM(NEWID()))%62 as fld14,
               abs(CHECKSUM(NEWID()))%62 as fld15,
               abs(CHECKSUM(NEWID()))%62 as fld16 into #tt
    from dbo.tblNumbers
    WHERE ID<= 100000;
    
    select [str], ROW_NUMBER() over(order by CHECKSUM(NEWID()))-1 as rn into #t
    from (select CHAR(ID+64) as [str] from dbo.tblNumbers where ID <= 26 union all
          select CHAR(ID+96) as [str] from dbo.tblNumbers where ID <= 26 union all
          select cast(ID-1 as varchar) as [str] from dbo.tblNumbers where ID <= 10) as t
    
    select tt.ID, left(t1.str + t2.str + t3.str + t4.str + t5.str + t6.str + t7.str + t8.str + 
                  t9.str + t10.str + t11.str + t12.str + t13.str + t14.str + t15.str + t16.str + REPLICATE(' ',1000),1000) as result
    into #tttt
    from #tt as tt join
            #t t1 on t1.rn = tt.fld1 join
            #t t2 on t2.rn = tt.fld2 join
            #t t3 on t3.rn = tt.fld3 join
            #t t4 on t4.rn = tt.fld4 join
            #t t5 on t5.rn = tt.fld5 join
            #t t6 on t6.rn = tt.fld6 join
            #t t7 on t7.rn = tt.fld7 join
            #t t8 on t8.rn = tt.fld8 join
            #t t9 on t9.rn = tt.fld9 join
            #t t10 on t10.rn = tt.fld10 join
            #t t11 on t11.rn = tt.fld11 join
            #t t12 on t12.rn = tt.fld12 join
            #t t13 on t13.rn = tt.fld13 join
            #t t14 on t14.rn = tt.fld14 join
            #t t15 on t15.rn = tt.fld15 join
            #t t16 on t16.rn = tt.fld16
            
    checkpoint
    DBCC DROPCLEANBUFFERS
    DBCC FREESYSTEMCACHE('all') 
    
    select dbo.ufn_MoveCharacterBackOrForwardByNPos(result,'forward',1), result from #tttt
    select dbo.ufn_clr_MoveCharacterBackOrForwardByNPos(result,'forward',1), result from #tttt
    
    select dbo.ufn_MoveCharacterBackOrForwardByNPos('oOv3lVLo4W3B44L7','forward',1)
    select dbo.ufn_clr_MoveCharacterBackOrForwardByNPos('oOv3lVLo4W3B44L7','forward',1)
    
    
    declare @int as int = 1;
    declare @cmd as varchar(max) = '';
    declare @cmdd as varchar(max) = '';
    declare @comand as varchar(max) = '';
    declare @comandd as varchar(max) = '';
    
    --select ISNULL(NULLIF(0,0),26)
    
    --select @@VERSION 
    while @int <= 101
    begin
        set @cmd = @cmd + 'substring(result,'+CAST(@int as varchar)+',1) as fld' +CAST(@int as varchar) + ','
        set @cmdd = @cmdd + 'case when ASCII(fld' +CAST(@int as varchar) + ') between 65 and 90 then CHAR(ISNULL(NULLIF((ASCII(fld' +CAST(@int as varchar) + ')-64+1)%26,0),26)+64) 
                                  when ASCII(fld' +CAST(@int as varchar) + ') between 97 and 122 then CHAR(ISNULL(NULLIF((ASCII(fld' +CAST(@int as varchar) + ')-64+1)%26,0),26)+64)
                                  when fld' +CAST(@int as varchar) + ' like ''[0-9]'' then CHAR(ISNULL(NULLIF((ASCII(fld' +CAST(@int as varchar) + ')-47+1)%10,0),10)+47) 
                                  else fld' +CAST(@int as varchar) + ' end +';
        
        if LEN(@cmd) > 7950
        begin
            set @comand = @comand + cast(@cmd as varchar(max))
            set @cmd = '';
        end
        
        if LEN(@cmdd) > 7950
        begin
            --print len(@cmdd)
            set @comandd = @comandd + cast(@cmdd as varchar(max))
            set @cmdd = '';
        end
        
        set @int = @int + 1
    end
    --select @cmdd
    if LEN(@cmd) > 0
        set @comand = 'select rtrim(result) AS result,' + @comand + cast(left(@cmd,len(@cmd)-1) as varchar(max)) + ' 
        from #tttt as a'
    --select @cmdd, LEN(@cmdd)
    --select @comandd, LEN(@cmdd)
    if LEN(@cmdd) > 0
        set @comandd = 'select rtrim(' + @comandd + cast(left(@cmdd,len(@cmdd)-1) as varchar(max)) + ') as final_str, result 
                        from (' + @comand + ') as t'
    
    --select @comandd
    EXEC( @comandd)
    
    --select * from #ttt
    
    CREATE TYPE udt_TwoCharacterColumn8000Long
    AS TABLE (
        col1 VARCHAR(8000) NULL,
        col2 VARCHAR(8000) NULL
    )
    
    alter PROCEDURE usp_UDTtest
        @t as udt_TwoCharacterColumn8000Long readonly
    as
    select * from @t
    
    declare @a as udt_TwoCharacterColumn8000Long
    
    insert into @a
    select 'abc', 'def'
    
    exec usp_UDTtest @a
  • 相关阅读:
    Error_OAF_the descriptive flexfield with application name payables and name is not frozen
    Error_OAF_Flex VO() of flex bean (ExpenseDescFlexs) is null (异常)
    AME_Oracle自带AME审批链详解AME Standard Handler(概念)
    PS_Form个性化复杂需求新增Menu并调用Request(案例)
    PS_Form个性化选择Block自动查询和查询条件排序实现(案例)
    Error_Unix Shell_syntax error near unexpected token `fi'
    PLSQL_性能优化效能跟踪工具DBMS_PROFILER分析(案例)
    Workflow_工作流的基本元素(概念)
    Form_如何通过标准功能查找数据源(概念)
    Report_SRW工具的基本用法(概念)
  • 原文地址:https://www.cnblogs.com/jenrrychen/p/4983559.html
Copyright © 2011-2022 走看看