2013-05-10 59 views
2

我買了一個SQL世界城市/州數據庫。在狀態數據庫中,它的狀態名稱拼合在一起。示例:「NorthCarolina」或「SouthCarolina」...查找大寫字母,然後添加空間

是否有一種方法在SQL中循環並查找大寫字符並添加空格?

這樣「NorthCarolina」變成「北卡羅萊納州」?

回答

0

有幾個方法可以解決這個

  1. 構造使用模式和PATINDEX feature功能。

  2. 鏈最小REPLACE語句每種情況下(如REPLACE(state_name, 'hC', 'h C' for your example case),這似乎是一種黑客攻擊,但實際上可能給你最好的性能,因爲你有這樣一個小套更換的。

+0

就像你打電話給PATINDEX功能 – cha 2013-05-10 02:18:53

+0

我以前試過PATINDEX。無法讓它與大寫字母一起工作。世界各國....所以它是很多數據。 – mrjamiebowman 2013-05-10 02:24:41

+0

@cha - 它是一種語言功能。你會怎麼稱呼它? – smartcaveman 2013-05-13 22:08:10

4

創建此功能

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); 
+0

男人......你釘了它。 :)這超出了完美。 – mrjamiebowman 2013-05-10 02:28:44

0

如果你絕對是不能創建函數並需要這個作爲一次性,你可以使用遞歸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 
相關問題