【问题标题】:I want to update values of a column in a table to Title case我想将表中列的值更新为标题大小写
【发布时间】:2019-06-11 21:16:00
【问题描述】:

我在数据库中有一个表,其中存在列名,我想将该名称字段中的值更新为标题大小写。

示例: "abc asd""Abc Asd"

考虑到表中有数百万条记录,我想知道使用 SQL 执行此操作的最佳方法是什么。

【问题讨论】:

  • 这个问题已经被问了数百次,甚至数千次。标题案例有很多警告,使用 t-sql 并不是一个很好的方法。这需要正则表达式和无数异常。
  • 我建议你在表示层上做这样的事情。这样会更快。
  • 或者做一些谷歌搜索/阅读google.com/…并试一试。

标签: sql sql-server


【解决方案1】:

数据卫生是一场持久战。正确的案例从来没有人们想象的那么简单。使用来自野外的数据时存在许多变化和不一致。

这是一个可以根据需要扩展的功能。

全面披露:还有许多其他性能更高的函数,但它们的方法往往过于简单。

示例

Declare @YourTable table (SomeCol varchar(100))
Insert Into @YourTable values
('old mcdonald'),
('dr. Langdon ,dds'),
('b&o railroad'),
('john-m-smith'),
('CARSON/jACOBS'),
('jAmes o''neil')

 Select *
       ,ProperCase = [dbo].[svf-Str-Proper](SomeCol)
 From @YourTable

退货

SomeCol             ProperCase
old mcdonald        Old McDonald
dr. Langdon ,dds    Dr. Langdon ,DDS
b&o railroad        B&O Railroad
john-m-smith        John-M-Smith
CARSON/jACOBS       Carson/Jacobs
jAmes o'neil        James O'Neil

有兴趣的 UDF

CREATE FUNCTION [dbo].[svf-Str-Proper] (@S varchar(max))
Returns varchar(max)
As
Begin
    Set @S = ' '+Replace(Replace(Lower(@S),'   ',' '),'  ',' ')+' '
    ;with cte1 as (Select * From (Values(' '),('-'),('/'),('\'),('['),('{'),('('),('.'),(','),('&'),(' Mc'),(' O''')) A(P))
         ,cte2 as (Select * From (Values('A'),('B'),('C'),('D'),('E'),('F'),('G'),('H'),('I'),('J'),('K'),('L'),('M')
                                       ,('N'),('O'),('P'),('Q'),('R'),('S'),('T'),('U'),('V'),('W'),('X'),('Y'),('Z')
                                       ,('LLC'),('PhD'),('MD'),('DDS')
                                 ) A(S))
         ,cte3 as (Select F = Lower(A.P+B.S),T = A.P+B.S From cte1 A Cross Join cte2 B ) 
    Select @S = replace(@S,F,T) From cte3
    Return rtrim(ltrim(@S))
End
-- Syntax :  Select [dbo].[svf-Str-Proper]('old mcdonald phd,dds llc b&o railroad')

【讨论】:

  • 是的,将这个添加到我的工具箱中,谢谢。
  • @scsimon 谢谢你的笑容。在我的世界中,cte1 和 cte2 中的数据位于通用映射表中……更易于维护和扩展。为了便于携带,我只是将内容放在 CTE 中。
【解决方案2】:

对于 基本 示例,使用像 Jeff Moden's 这样的计数表字符串拆分器,或者您想要的任何拆分函数来代替下面的 DelimitedSplit8K(),您可以在空格上拆分它们,然后修复正确的外壳后将它们重新组合在一起。请注意,使用这种类型的拆分函数比常见的 RBAR(while 循环等)方法更快。

DEMO

declare @table table (v varchar(4000))
insert into @table
values
('abc abc abc'),
('Def abc ABC'),
('qrs ABC abc'),
('tuv'),
(' this is an odd-string# that3 has some 435 in it. It has leading and trailing spaces? ')

select distinct
    *
    ,STUFF((
          SELECT ' ' + upper(left(lower(rtrim(ltrim(x.Item))),1)) + right(lower(rtrim(ltrim(x.Item))),len(rtrim(ltrim(x.Item))) - 1)
          from @table t
          cross apply DelimitedSplit8K(rtrim(ltrim(v)),' ') x
          where t.v = b.v
          FOR XML PATH(''), TYPE).value('.', 'NVARCHAR(MAX)'), 1, 1, '') 
from @table b

【讨论】:

    猜你喜欢
    • 2010-11-24
    • 1970-01-01
    • 2017-05-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-03-24
    • 1970-01-01
    • 2017-09-15
    相关资源
    最近更新 更多