Finding Uppercase Character then Adding Space

后端 未结 3 768
梦毁少年i
梦毁少年i 2021-01-20 03:12

I bought a SQL World City/State database. In the state database it has the state names pushed together. Example: \"NorthCarolina\", or \"SouthCarolina\"...

IS there

相关标签:
3条回答
  • 2021-01-20 03:50

    Create this function

    if object_id('dbo.SpaceBeforeCaps') is not null
        drop function dbo.SpaceBeforeCaps
    GO
    create function dbo.SpaceBeforeCaps(@s varchar(100)) returns varchar(100)
    as
    begin
        declare @return varchar(100);
        set @return = left(@s,1);
        declare @i int;
        set @i = 2;
        while @i <= len(@s)
        begin
            if ASCII(substring(@s,@i,1)) between ASCII('A') and ASCII('Z')
                set @return = @return + ' ' + substring(@s,@i,1)
            else
                set @return = @return + substring(@s,@i,1)
            set @i = @i + 1;
        end;
        return @return;
    end;
    GO
    

    Then you can use it to update your database

    update tbl set statename = select dbo.SpaceBeforeCaps(statename);
    
    0 讨论(0)
  • 2021-01-20 04:00

    There's a couple ways to approach this

    1. Construct a function using a pattern and the PATINDEX feature.

    2. Chain minimal REPLACE statements for each case (e.g. REPLACE(state_name, 'hC', 'h C' for your example case). This seems is kind of a hack, but might actually give you the best performance, since you have such a small set of replacements.

    0 讨论(0)
  • 2021-01-20 04:16

    If you absolutely cannot create functions and need this as a one-off, you can use a recursive CTE to break the string up (and add the space at the same time where required), then recombine the characters using FOR XML. Elaborate example below:

    -- some sample data
    create table #tmp (id int identity primary key, statename varchar(100));
    insert #tmp select 'NorthCarolina';
    insert #tmp select 'SouthCarolina';
    insert #tmp select 'NewSouthWales';
    
    -- the complex query updating the "statename" column in the "#tmp" table
    ;with cte(id,seq,char,rest) as (
        select id,1,cast(left(statename,1) as varchar(2)), stuff(statename,1,1,'')
          from #tmp
         union all
        select id,seq+1,case when ascii(left(rest,1)) between ascii('A') and ascii('Z')
                             then ' ' else '' end + left(rest,1)
             , stuff(rest,1,1,'')
          from cte
         where rest > ''
    ), recombined as (
      select a.id, (select b.char+''
                      from cte b
                     where a.id = b.id
                  order by b.seq
                       for xml path, type).value('/','varchar(100)') fixed
        from cte a
    group by a.id
    )
    update t
       set statename = c.fixed
      from #tmp t
      join recombined c on c.id = t.id
     where statename != c.fixed;
    
    -- check the result
    select * from #tmp
    
    ----------- -----------
    id          statename
    ----------- -----------
    1           North Carolina
    2           South Carolina
    3           New South Wales
    
    0 讨论(0)
提交回复
热议问题