Proper / Title Case SQL Server中带有Exceptions表的列

时间:2016-07-07 21:37:38

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

我正在尝试将大写的列转换为正确的大小写,但是有一些缩写,例如某些首字母缩略词,缩写。我按照下面的代码来实现它。但看起来这将是一个持续的过程,所以,我想创建一个具有异常的表,以便清理数据,我希望能够从函数中调用例外表。如果有人能帮助我处理他们所拥有的与此类似的任何代码或任何有关如何实现它的想法,那将是很棒的。

ALTER FUNCTION [dbo].[Business_ProperCase]
     (@Text AS VARCHAR(8000)) 
RETURNS VARCHAR(8000) 
AS 
BEGIN 
    -- declare some variables 
    DECLARE @Reset BIT; DECLARE @Ret VARCHAR(8000); DECLARE @i INT; 
    DECLARE @c0 CHAR(1); DECLARE @c1 CHAR(1); DECLARE @c2 CHAR(1); 
    DECLARE @CaseLen INT; 
    DECLARE @CaseExceptions VARCHAR(8000); 
    DECLARE @CaseValue VARCHAR(8000); 

    -- Set some default values 
    SELECT @Reset = 1, @i=1, @Ret = ''; 

    -- only apply if all characters are already in uppercase 
    IF (UPPER(@Text)=@Text COLLATE Latin1_General_CS_AI) 
         BEGIN 

                 -- add a leading and trailing space to indicate word delimiters (bol & eol) 
                 SET @Text = ' ' + @Text + ' '; 

                 -- cycle through each character, 
                 -- if non-alpha, uppercase next alpha character. 
                 -- if alpha then lowercase subsequent alphas. 
                 WHILE (@i <= LEN(@Text)) 
                         SELECT 
                                 @c0=SUBSTRING(@Text,@i-2,1), @c1=SUBSTRING(@Text,@i-1,1), @c2=SUBSTRING(@Text,@i,1), 
                                 @Ret = @Ret + CASE WHEN @Reset=1 THEN UPPER(@c2) ELSE LOWER(@c2) END, 
                                 @Reset = CASE 
                                                                                             WHEN @c0 = ' ' AND @c1 = 'M' AND @c2 = 'c' THEN 1 

                                                 WHEN @c0 = ' ' AND @c1 IN ('D', 'I', 'O') AND @c2 = '''' THEN 1 


                                                 WHEN @c2 LIKE '[a-zA-Z'']' THEN 0               -- Apply LOWER to any character after alphas or apostrophes 
                                                ELSE 1                                                                  -- Apply UPPER to any character after symbols/punctuation 
                                         END, 
                                 @i = @i +1 

                 -- add a trailing space in case the previous rule changed this. 
                 SET @Ret = @Ret + ' '; 

                 -- custom exceptions: this search is case-insensitive and will 
                 -- replace the word to the case as it is written in the list. 
                 -- NOTE: this list has to end with a comma! 
                 SELECT @i=0, @CaseLen=0, 
                         @CaseExceptions = 'ABS,LLC,MD,MBA,MA,

--Want to create a table for these exceptions and call them from this function 
                 -- Loop through exception cases 
                 WHILE CHARINDEX(',', @CaseExceptions, @i+1)>0 
                         BEGIN 
                                 -- get the delimited word 
                                 SET @CaseLen = CHARINDEX(',', @CaseExceptions, @i+1) - @i 
                                 SET @CaseValue = SUBSTRING(@CaseExceptions, @i, @CaseLen) 

                                 -- replace it in the original text 
                                 SET @Ret = REPLACE(@Ret, ' '+@CaseValue+' ', ' '+@CaseValue+' ') 

                                 -- get position of next word 
                                 SET @i = CHARINDEX(',', @CaseExceptions, @i+@CaseLen) +1 
                         END 

                 -- remove any leading and trailing spaces 
                 SET @Ret = LTRIM(RTRIM(@Ret)); 

                 -- capitalize first character of data irrespective of previous rules 
                 SET @Ret = UPPER(SUBSTRING(@Ret,1,1)) + SUBSTRING(@Ret,2,LEN(@Ret)); 

         END 
    ELSE 
     BEGIN 
                 -- return the string unaffected if it is not in uppercase 
                 SET @Ret=@Text 
         END 

    RETURN @Ret 
 END 

4 个答案:

答案 0 :(得分:1)

创建一个带有EXCEPTION列的表(我以TITLE_CASE_EXCEPTION为例) 然后是从那里驱动数据。

conda update --all

答案 1 :(得分:0)

以下是您参考的示例:

declare @s varchar(256) = 'This is a SQL test';
declare @t table (ignore varchar(256) not null);

insert into @t (ignore) values ('SQL');

declare @pos int = 1;
declare @nextpos int;
declare @w varchar(256);

while @pos <= len(@s)
begin
    set @nextpos = charindex(' ', @s + ' ', @pos);
    set @w = substring(@s, @pos, @nextpos - @pos);
    if not exists (select 1 from @t where ignore = @w)
        set @s = stuff(
            @s, @pos, @nextpos - @pos,
            stuff(lower(@w), 1, 1, upper(left(@w, 1)))
        );
    set @pos = @nextpos + 1;
    select @s;
end

答案 2 :(得分:0)

要回答原始请求..设置一个表“Exceptions”,其中包含一个类型为nvarchar(100)的ConcatList,并将异常添加到此表中...然后创建一个视图,将它们连接在一起...

    create table exceptions (ConcatList nvarchar(100))

    create view [dbo].vExceptions
    as
     Select distinct
        substring(
        (
            Select ','+ up.ConcatList  AS [text()]
            From exceptions up 
            ORDER BY up.ConcatList
            For XML PATH ('')
        ), 2, 4000) [exceptions]

     From exceptions p

以下是该问题的存储过程的略微增强版本。  (虽然这是一个公认的不优雅的解决方案)可以解释:

  • 小写单词(of,the,an等)
  • Hhyphenated acronyms
  • 短划线或逗号之前或之后的异常。

    alter FUNCTION [dbo].[Business_ProperCase]
         (@Text AS VARCHAR(8000)) 
    RETURNS VARCHAR(8000) 
    AS 
    BEGIN 
        -- declare some variables 
        DECLARE @Reset BIT; DECLARE @Ret VARCHAR(8000); DECLARE @i INT; 
        DECLARE @c0 CHAR(1); DECLARE @c1 CHAR(1); DECLARE @c2 CHAR(1); 
        DECLARE @CaseLen INT; 
        DECLARE @CaseExceptions VARCHAR(8000); 
        DECLARE @CaseValue VARCHAR(8000); 
    
        -- Set some default values 
        SELECT @Reset = 1, @i=1, @Ret = ''; 
    
        -- only apply if all characters are already in uppercase 
        IF (UPPER(@Text)=@Text COLLATE Latin1_General_CS_AI) 
             BEGIN 
    
                     -- add a leading and trailing space to indicate word delimiters (bol & eol) 
                     SET @Text = ' ' + @Text + ' '; 
    
                     -- cycle through each character, 
                     -- if non-alpha, uppercase next alpha character. 
                     -- if alpha then lowercase subsequent alphas. 
                     WHILE (@i <= LEN(@Text)) 
                             SELECT 
                                     @c0=SUBSTRING(@Text,@i-2,1), @c1=SUBSTRING(@Text,@i-1,1), @c2=SUBSTRING(@Text,@i,1), 
                                     @Ret = @Ret + CASE WHEN @Reset=1 THEN UPPER(@c2) ELSE LOWER(@c2) END, 
                                     @Reset = CASE WHEN @c0 = ' ' AND @c1 = 'M' AND @c2 = 'c' THEN 1 
                                                   WHEN @c0 = ' ' AND @c1 IN ('D', 'I', 'O') AND @c2 = '''' THEN 1 
                                                   WHEN @c2 LIKE '[a-zA-Z'']' THEN 0               -- Apply LOWER to any character after alphas or apostrophes 
                                                    ELSE 1                                         -- Apply UPPER to any character after symbols/punctuation 
                                              END, 
                                     @i = @i +1 
    
                     -- add a trailing space in case the previous rule changed this. 
                     SET @Ret = @Ret + ' '; 
    
                     -- custom exceptions: this search is case-insensitive and will 
                     -- replace the word to the case as it is written in the list. 
                     -- NOTE: this list has to end with a comma! 
                     SELECT @i=0, @CaseLen=0, 
                             @CaseExceptions = exceptions from vExceptions
    
    --Want to create a table for these exceptions and call them from this function 
                     -- Loop through exception cases 
                     WHILE CHARINDEX(',', @CaseExceptions, @i+1)>0 
                             BEGIN 
                                     -- get the delimited word 
                                     SET @CaseLen = CHARINDEX(',', @CaseExceptions, @i+1) - @i 
                                     SET @CaseValue = SUBSTRING(@CaseExceptions, @i, @CaseLen) 
                                     if (@CaseValue = 'OF' or @CaseValue = 'AND' or @CaseValue ='THE' or @CaseValue='FOR')
                                     begin
                                         --replace with lower case 'of', 'and', 'the', 'for'
                                         SET @Ret = REPLACE(@Ret, ' '+@CaseValue+' ', ' '+lower(@CaseValue)+' ') 
                                     end
                                     else
                                     begin  
                                        if (CHARINDEX(' '+ @CaseValue +' ', @Ret)>0 )
                                        begin
                                             -- replace it in the original text 
                                             SET @Ret = REPLACE(@Ret, ' '+@CaseValue+' ', ' '+@CaseValue+' ') 
                                        end
                                        else if (CHARINDEX(' '+@CaseValue+',', @Ret)>0 )
                                        begin
                                            --replace text (with no spaces around it)
                                            SET @Ret = REPLACE(@Ret, ' '+@CaseValue+',', ' '+@CaseValue+',') 
                                        end
                                        else if (CHARINDEX(' '+@CaseValue+'-', @Ret)>0 )
                                        begin
                                            --replace text (with no spaces around it)
                                            SET @Ret = REPLACE(@Ret, ' '+@CaseValue+'-', ' '+@CaseValue+'-') 
                                        end
                                        else if (CHARINDEX('-'+@CaseValue+' ', @Ret)>0 )
                                        begin
                                            --replace text (with no spaces around it)
                                            SET @Ret = REPLACE(@Ret, '-'+@CaseValue+' ', '-'+@CaseValue+' ') 
                                        end
                                        else if (CHARINDEX(','+@CaseValue+' ', @Ret)>0 )
                                        begin
                                            --replace text (with no spaces around it)
                                            SET @Ret = REPLACE(@Ret, ','+@CaseValue+' ', '-'+@CaseValue+' ') 
                                        end
                                     end
    
                                     -- get position of next word 
                                     SET @i = CHARINDEX(',', @CaseExceptions, @i+@CaseLen) +1 
                             END 
    
                     -- remove any leading and trailing spaces 
                     SET @Ret = LTRIM(RTRIM(@Ret)); 
    
                     -- capitalize first character of data irrespective of previous rules 
                     SET @Ret = UPPER(SUBSTRING(@Ret,1,1)) + SUBSTRING(@Ret,2,LEN(@Ret)); 
    
             END 
        ELSE 
         BEGIN 
                     -- return the string unaffected if it is not in uppercase 
                     SET @Ret=@Text 
             END 
    
        RETURN @Ret 
     END 
    

答案 3 :(得分:0)

创建一个带有列404 page not found的表(我以ExceptionsTable为例)。然后在页面顶部的最后一个WordExcepts之后添加以下内容:

DECLARE

然后在下面将您的例外情况调整为:

DECLARE @sql nvarchar(2000);

SET @sql = 'N select WordExcepts from ExceptionsTable' 

只需根据需要添加到表中,它们就会从函数中过滤掉。