【问题标题】:Finding Uppercase Character then Adding Space查找大写字符然后添加空格
【发布时间】:2013-05-04 15:43:51
【问题描述】:

我购买了一个 SQL World City/State 数据库。在状态数据库中,它将状态名称放在一起。示例:“北卡罗来纳”或“南卡罗来纳”...

SQL 中有没有办法循环查找大写字符并添加空格???

这样“北卡罗来纳”就变成了“北卡罗来纳”???

【问题讨论】:

    标签: sql uppercase


    【解决方案1】:

    创建这个函数

    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
    

    然后你就可以用它来更新你的数据库了

    update tbl set statename = select dbo.SpaceBeforeCaps(statename);
    

    【讨论】:

      【解决方案2】:

      有几种方法可以解决这个问题

      1. 使用模式和PATINDEX feature 构造函数。

      2. 每个案例的链式最小 REPLACE 语句(例如 REPLACE(state_name, 'hC', 'h C' for your example case)。这似乎是一种 hack,但实际上可能会给你最好的性能,因为你有这么少的替代品。

      【讨论】:

      • 就像你如何调用 PATINDEX 功能
      • 我之前尝试过 PATINDEX。无法找到大写字母。世界各国....所以它有很多数据。
      • @cha - 这是一种语言功能。你会怎么称呼它?
      • 不想冒犯你。有时在我们的团队中,我们将错误称为“未记录的功能”en.wikipedia.org/wiki/Undocumented_feature
      【解决方案3】:

      如果您绝对不能创建函数并且需要一次性使用,您可以使用递归 CTE 来分解字符串(并在需要的同时添加空格),然后使用 FOR XML 重新组合字符。详细示例如下:

      -- 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
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-05-31
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-07-26
        相关资源
        最近更新 更多