2016-07-07 2 views
-1

Я пытаюсь преобразовать столбец, который находится в верхнем регистре, в соответствующий регистр, но с исключениями, такими как некоторые сокращения, аббревиатуры. Я выполняю приведенный ниже код для его реализации. Но похоже, что это будет непрерывный процесс, и поэтому я хочу создать таблицу с исключениями, чтобы упростить очистку данных, и я хочу, чтобы можно было вызвать таблицу исключений из этой функции. Было бы здорово, если бы кто-нибудь мог помочь мне с любыми кодами, которые у них есть, которые похожи на это или на любые идеи о том, как его реализовать.Правильный/заголовок Случай столбца с таблицей исключений в SQL Server

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)[email protected] 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, ' '[email protected]+' ', ' '[email protected]+' ') 

           -- get position of next word 
           SET @i = CHARINDEX(',', @CaseExceptions, @[email protected]) +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 @[email protected] 
     END 

    RETURN @Ret 
END 
+0

точно, как это не работает? –

+0

Это прекрасно работает, Марк. Но я хочу сделать исключения в виде таблицы, где я могу иметь все исключения в одном месте или даже модифицировать ее, чтобы включить ошибки орфографии в столбец и использовать замену или что-то из таблицы. Я не уверен, как это сделать. – user6562697

+0

Вы должны уметь выбирать слова, а не только отдельные символы. Итерации над словами с помощью 'set @nextpos = charindex ('', @text, @lastpos)' и 'set @word = substring (@text, @lastpos + 1, @nextpos - @lastpos - 1)'. Затем проверьте, находится ли '@ word' в вашем списке исключений. – shawnt00

ответ

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

спасибо за ответ. Однако я хочу сделать следующее. После того, как шрифты были преобразованы в соответствующий случай, я хочу передать полученную строку в таблицу исключений с одним столбцом в качестве подстроки, которую нужно изменить, и с другим столбцом в качестве итоговой строки. Таким образом, я не должен упоминать исключения в функции, но могу вызвать таблицу исключений из функции. Любая помощь будет высоко ценится! – user6562697

+0

@ user6562697 Если вы хотите сделать это так, то какова была цель публикации функции выше в первую очередь? И разве у вас все еще есть одна и та же проблема расщепления правильной оберточной струны на более мелкие маркеры? Мой был просто образцом для подхода к нему. Я думаю, что вас там много предстоит изучить. – shawnt00

+0

Согласен. Существует много возможностей для изучения. Функция, которую я опубликовал, - это мой способ справиться с исключениями, которые произошли в именах, содержащихся в столбце. Но в долгосрочной перспективе я не хочу каждый раз редактировать функцию, а скорее вызывать таблицу из самой функции для исключений и посмотреть, как это происходит. Спасибо – user6562697

0

Чтобы ответить на первоначальный запрос .. создать таблицу «Исключение» с одной колонкой ConcatList типа NVARCHAR (100) и добавить исключения из этой таблицы ... затем создать представление с, чтобы объединить их вместе ...

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 

Вот немного расширенная версия хранимой процедуры от вопроса. (хотя по общему признанию безвкусный раствор) для учета:

  • строчными буквами слов (из, то, ап, и т.д.)
  • Hhyphenated акронимы
  • Исключения, которые немедленно предшествует или следует с тире или запятая.

    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)[email protected] 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, ' '[email protected]+' ', ' '+lower(@CaseValue)+' ') 
               end 
               else 
               begin 
                if (CHARINDEX(' '+ @CaseValue +' ', @Ret)>0) 
                begin 
                 -- replace it in the original text 
                 SET @Ret = REPLACE(@Ret, ' '[email protected]+' ', ' '[email protected]+' ') 
                end 
                else if (CHARINDEX(' '[email protected]+',', @Ret)>0) 
                begin 
                 --replace text (with no spaces around it) 
                 SET @Ret = REPLACE(@Ret, ' '[email protected]+',', ' '[email protected]+',') 
                end 
                else if (CHARINDEX(' '[email protected]+'-', @Ret)>0) 
                begin 
                 --replace text (with no spaces around it) 
                 SET @Ret = REPLACE(@Ret, ' '[email protected]+'-', ' '[email protected]+'-') 
                end 
                else if (CHARINDEX('-'[email protected]+' ', @Ret)>0) 
                begin 
                 --replace text (with no spaces around it) 
                 SET @Ret = REPLACE(@Ret, '-'[email protected]+' ', '-'[email protected]+' ') 
                end 
                else if (CHARINDEX(','[email protected]+' ', @Ret)>0) 
                begin 
                 --replace text (with no spaces around it) 
                 SET @Ret = REPLACE(@Ret, ','[email protected]+' ', '-'[email protected]+' ') 
                end 
               end 
    
               -- get position of next word 
               SET @i = CHARINDEX(',', @CaseExceptions, @[email protected]) +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 @[email protected] 
         END 
    
        RETURN @Ret 
    END 
    
Смежные вопросы