用条件制作每个单词大写的第一个字母

时间:2016-03-23 13:59:50

标签: sql sql-server sql-server-2008-r2

我的文字看起来像VENDOR CORPORATION (GA/ATL)。我想让它看起来像Vendor Corporation (GA/ATL)

所以,除了()之间存在的那些词之外,我想只做出每个单词大写的第一个字母。

我遇到了 - UPPER(LEFT(FIELD_NAME,1))+LOWER(SUBSTRING(FIELD_NAME,2,LEN(FIELD_NAME))),但它一次只能处理一个单词并且没有我想要的功能。最需要的是能够完成工作的功能。

3 个答案:

答案 0 :(得分:2)

尝试使用function,如下所示:

BEGIN

DECLARE @Index          INT
DECLARE @Char           CHAR(1)
DECLARE @PrevChar       CHAR(1)
DECLARE @OutputString   VARCHAR(255)

SET @OutputString = LOWER(@InputString)
SET @Index = 1

WHILE @Index <= LEN(@InputString)
BEGIN
    SET @Char     = SUBSTRING(@InputString, @Index, 1)
    SET @PrevChar = CASE WHEN @Index = 1 THEN ' '
                         ELSE SUBSTRING(@InputString, @Index - 1, 1)
                    END

    IF @PrevChar IN (' ', ';', ':', '!', '?', ',', '.', '_', '-', '/', '&', '''', '(')
    BEGIN
        IF  @PrevChar != '(' AND @PrevChar != '/'
            SET @OutputString = STUFF(@OutputString, @Index, 1, UPPER(@Char))
        IF  @PrevChar = '(' 
            SET @OutputString = LEFT(@OutputString, LEN(@OutputString) - LEN(SUBSTRING(@OutputString, CHARINDEX('(',@OutputString), CHARINDEX(')',@OutputString)))) +  UPPER(SUBSTRING(@OutputString, CHARINDEX('(',@OutputString), CHARINDEX(')',@OutputString)))
    END

    SET @Index = @Index + 1
END

RETURN @OutputString

END

<强> USAGE

SELECT [dbo].[InitCap]('VENDOR CORPORATION (GA/ATL)')

<强>输出

Vendor Corporation (GA/ATL)

答案 1 :(得分:2)

使用Jeff Moden分离器(可以在这里找到。http://www.sqlservercentral.com/articles/Tally+Table/72993/)这可以实现。然后,您需要使用交叉表(也称为条件聚合)将片段重新组合在一起。您也可以使用PIVOT执行此操作,但我发现交叉选项卡的语法不那么迟钝,并且已经证明性能稍微快一些。这也是使用此处的InitCap函数。 How to update data as upper case first letter with t-sql command?

declare @Value varchar(100) = 'VENDOR CORPORATION (GA/ATL)';

with sortedValues as
(
    select Case when left(s.Item, 1) = '(' then s.Item else dbo.InitCap(s.Item) end as CorrectedVal
        , s.ItemNumber
    from dbo.DelimitedSplit8K(@Value, ' ') s
)

select MAX(case when ItemNumber = 1 then CorrectedVal end) + ' '
     + MAX(case when ItemNumber = 2 then CorrectedVal end) + ' '
     + MAX(case when ItemNumber = 3 then CorrectedVal end)
from sortedValues

如果您事先不知道您将拥有多少“单词”,则可以将此交叉表调整为动态版本。您可以在此处阅读有关动态交叉表的更多信息。 http://www.sqlservercentral.com/articles/Crosstab/65048/

- 编辑 -

感谢JamieD77使用STUFF的建议。我特别喜欢这个选项,因为我有另一个版本的InitCap使用了一个计数表而不是这里引用的版本,它使用了一个while循环。使用STUFF有助于将整个事物转换为内联表值函数,因此它将非常快。如果有人想在没有循环的情况下看到InitCap让我知道,我会很乐意发布它。

以下是使用建议的STUFF方法的查询。

SELECT STUFF((SELECT   ' ' + s.CorrectedVal
    FROM sortedValues s
    ORDER BY s.ItemNumber
    FOR
    XML PATH('')
    ),1,1,'')

答案 2 :(得分:2)

作为上述答案的替代方案。如果您想忽略()之间的内容,可以使用InitCap函数的这个稍微修改过的版本

CREATE FUNCTION [dbo].[InitCap] (
     @InputString VARCHAR(4000)
    )
RETURNS VARCHAR(4000)
AS 
    BEGIN

        DECLARE @Index INT
        DECLARE @Char CHAR(1)
        DECLARE @PrevChar CHAR(1) = ' '
        DECLARE @OutputString VARCHAR(255)
        SET @OutputString = LOWER(@InputString)
        SET @Index = 1
        WHILE @Index <= LEN(@InputString) 
            BEGIN
                SET @Char = SUBSTRING(@InputString,@Index,1)
                IF @Char = '(' 
                    BEGIN
                        WHILE @Index <= LEN(@InputString)
                            AND @Char NOT IN (')') 
                            BEGIN 
                                SET @Index = @Index + 1
                                SET @PrevChar = @Char
                                SET @Char = SUBSTRING(@InputString,@Index,1)
                                SET @OutputString = STUFF(@OutputString,@Index,1,@Char)
                            END
                    END              
                IF @PrevChar IN (' ',';',':','!','?',',','.','_','-','/','&','''') 
                    BEGIN
                        IF @PrevChar != ''''
                            OR UPPER(@Char) != 'S' 
                            SET @OutputString = STUFF(@OutputString,@Index,1,UPPER(@Char))
                    END
                SET @Index = @Index + 1
                SET @PrevChar = @Char
            END
        RETURN @OutputString
    END
GO

示例

SELECT  [dbo].[InitCap](n)
FROM    ( VALUES ( 'VENDOR CORPORATION (GA/ATL)'), 
                 ( 'VENDOR CORPORATION (ga/atl)'), 
                 ( 'VENDOR CORPORATION (Ga/Atl)') ) t (n)

output
--------
Vendor Corporation (GA/ATL)
Vendor Corporation (ga/atl)
Vendor Corporation (Ga/Atl)

如果你总是希望在()内填写所有内容,只需在两个地方使用SET @OutputString = STUFF(@OutputString,@Index,1,UPPER(@Char))