Есть ли встроенная функция SQL Server для преобразования строки в случае верблюда? - PullRequest
11 голосов
/ 02 марта 2011

Я не хочу создавать пользовательскую функцию для этого, если она уже существует в SQL Server

Входная строка: This is my string to convert
Ожидаемый вывод: This Is My String To Convert

Ответы [ 6 ]

23 голосов
/ 02 марта 2011
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
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)
    SET @PrevChar = CASE WHEN @Index = 1 THEN ' '
                         ELSE SUBSTRING(@InputString, @Index - 1, 1)
                    END

    IF @PrevChar IN (' ', ';', ':', '!', '?', ',', '.', '_', '-', '/', '&', '''', '(')
    BEGIN
        IF @PrevChar != '''' OR UPPER(@Char) != 'S'
            SET @OutputString = STUFF(@OutputString, @Index, 1, UPPER(@Char))
    END

    SET @Index = @Index + 1
END

RETURN @OutputString

END



Declare @str nvarchar(100)
SET @str = 'my string to convert'
SELECT @str = [dbo].[InitCap](@str)
SELECT @str 
7 голосов
/ 02 марта 2011

AFAIK, SQL Server не имеет встроенной функции для этого.
Вы должны написать пользовательскую функцию для этого.

Попробуй это.

CREATE FUNCTION [dbo].[CamelCase]
(@Str varchar(8000))
RETURNS varchar(8000) AS
BEGIN
  DECLARE @Result varchar(2000)
  SET @Str = LOWER(@Str) + ' '
  SET @Result = ''
  WHILE 1=1
  BEGIN
    IF PATINDEX('% %',@Str) = 0 BREAK
    SET @Result = @Result + UPPER(Left(@Str,1))+
    SubString  (@Str,2,CharIndex(' ',@Str)-1)
    SET @Str = SubString(@Str,
      CharIndex(' ',@Str)+1,Len(@Str))
  END
  SET @Result = Left(@Result,Len(@Result))
  RETURN @Result
END  

Выход:

Input String    : 'microSoft sql server'
Output String   : 'Microsoft Sql Server'
6 голосов
/ 02 марта 2011

Я должен был бы пойти с «Нет, это не существует».Это основано на нескольких годах изучения доступных строковых функций в T-SQL и некоторых недавних пятидневных курсах по SQL Server 2008 R2.

Конечно, я все еще могу ошибаться:).

4 голосов
/ 27 ноября 2013

Если целью вашей операции является предварительное присвоение строк имен, то правильная заглавная буква может быть определена как первая буква каждого слова, разделенная не алфавитными символами.

Другие решения не учитывают:

  1. Сохранение пробелов (особенно конечных пробелов).
  2. Сохранение NULL, пустой строки или строки из просто пробелов.
  3. Обработка не только пробелов (например, тире), запятые, подчеркивания и т. д.)
  4. Обработка более чем одного не альфа-символа между словами / токенами.
  5. Обработка исключений (например, Макдональд или III, как в «Джеймсе Уильяме Боттомуз III").

Примечание. Мое решение не обрабатывает исключения.Если вы очень обеспокоены этим, то я предлагаю написать сборку CLR C # для них, так как это будет сложно, и строки - это область, где C # превосходит.Другое решение здесь пытается объяснить это, но все равно потребуются " ivan ужасный iv " и вывод "** IV *** ужасный IV *".

Thisэто функция, которую я придумал:

IF  EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[fs_PascalCase]') AND type in (N'FN', N'IF', N'TF', N'FS', N'FT'))
DROP FUNCTION [dbo].[fs_PascalCase]
GO
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE FUNCTION [dbo].[fs_PascalCase]
(
    @Text nVarChar(MAX)
)
RETURNS nVarChar(MAX)
AS
BEGIN
        SET @Text = LOWER(@Text)--This step is optional.  Keep if you want the code below to control all casing. - 11/26/2013 - MCR.
    DECLARE @New nVarChar(MAX) = (CASE WHEN @Text IS NULL THEN NULL ELSE '' END)--Still return null when source is null. - 11/26/2013 - MCR.
    DECLARE @Len   Int = LEN(REPLACE(@Text, ' ', '_'))--If you want to count/keep trailing-spaces, you MUST use this!!! - 11/26/2013 - MCR.
    DECLARE @Index Int = 1--Sql-Server is 1-based, not 0-based.
    WHILE (@Index <= @Len)
        IF (SUBSTRING(@Text, @Index, 1) LIKE '[^a-z]' AND @Index + 1 <= @Len)--If not alpha and there are more character(s).
            SELECT @New = @New + UPPER(SUBSTRING(@Text, @Index, 2)), @Index = @Index + 2
        ELSE
            SELECT @New = @New +       SUBSTRING(@Text, @Index, 1) , @Index = @Index + 1

    --If @Text is null, then @Len will be Null, and everything will be null.
    --If @Text is '',   then (@Len - 1) will be -1, so ABS() it to use 1 instead, which will still return ''.
    RETURN ( UPPER(LEFT(@New, 1)) + RIGHT(@New, ABS(@Len - 1)) )
END
GO

Вы бы назвали это так:

SELECT dbo.fs_PascalCase(NULL)[Null],
       dbo.fs_PascalCase('')[EmptyString],
       dbo.fs_PascalCase('hello   how are-you TODAY    ')[LongString]

Вывод будет выглядеть так:PascalCase Output

2 голосов
/ 06 октября 2011

Моя стратегия

  • Если имя уже в смешанном регистре, поверьте, что оно верно.
  • Если имя не в смешанном регистре, сделайте следующее:
  • Обрезать имя, чтобы устранить пробелы
  • Учет имен, начинающихся с «Mc», например «McDavid»
  • Учет имен с апострофами, такими как O’Reilly
  • Учет дефисных имен (фамилий) «Андерсон-Джонсон»
  • Учетная запись для нескольких слов, например «La Russa»
  • Убедитесь, что суффиксы, включенные в поле имен, написаны заглавными буквами

Код

Вот мой оригинальный пост: Преобразование строки в регистр верблюдов в SQL Server

CREATE FUNCTION [dbo].[GetCamelCaseName]
(
    @Name varchar(50)
)
RETURNS VARCHAR(50) WITH SCHEMABINDING
AS
BEGIN
    -- Declare the return variable here
    DECLARE @NameCamelCase VARCHAR(50)  

    -- This is determining whether or not the name is in camel case already (if the 1st character is uppercase
    -- and the third is lower (because the 2nd could be an apostrophe).  To do this, you have to cast the 
    -- character as varbinary and compare it with the upper case of the character cast as varbinary.  

    IF (CAST(SUBSTRING(@Name, 1,1) as varbinary) = CAST(SUBSTRING(UPPER(@Name), 1, 1) as varbinary)         
            AND ((CAST(SUBSTRING(@Name, 2,1) as varbinary) = CAST(SUBSTRING(LOWER(@Name), 2, 1) as varbinary)
                    AND SUBSTRING(@Name, 2,1) != '''')
                or
                (CAST(SUBSTRING(@Name, 4,1) as varbinary) = CAST(SUBSTRING(LOWER(@Name), 4, 1) as varbinary)
                    AND SUBSTRING(@Name, 2,1) = '''')))

        BEGIN
            SELECT @NameCamelCase = RTRIM(LTRIM(@Name))
            SELECT @NameCamelCase = REPLACE(@NameCamelCase, ' sr', ' Sr')           
            SELECT @NameCamelCase = REPLACE(@NameCamelCase, ' jr', ' Jr')       
            SELECT @NameCamelCase = REPLACE(@NameCamelCase, ' ii', ' II')   
            SELECT @NameCamelCase = REPLACE(@NameCamelCase, ' iii', ' III')
            SELECT @NameCamelCase = REPLACE(@NameCamelCase, ' DE ', ' de ')
            SELECT @NameCamelCase = REPLACE(@NameCamelCase, 'macdonald', 'MacDonald')

            if (@NameCamelCase LIKE '% iv') -- avoid changing "Ivan" to "IVan"
                SELECT @NameCamelCase = REPLACE(@NameCamelCase, ' iv', ' IV')

            if ((@NameCamelCase = 'i') or (@NameCamelCase = 'ii') or (@NameCamelCase = 'iii') or (@NameCamelCase = 'iv'))
                SELECT @NameCamelCase = UPPER(@NameCamelCase)

            RETURN @NameCamelCase       

        END

    ELSE

        BEGIN       

            SELECT @NameCamelCase = RTRIM(LTRIM(@Name))

            -- "Mc-"
            SELECT @NameCamelCase = 
                CASE 
                    WHEN @Name LIKE 'mc%'
                        THEN UPPER(SUBSTRING(@Name, 1, 1)) + LOWER(SUBSTRING(@Name, 2, 1)) + UPPER(SUBSTRING(@Name, 3, 1))  + LOWER(SUBSTRING(@Name, 4, 47))
                    ELSE
                       UPPER(SUBSTRING(@Name, 1, 1)) + LOWER(SUBSTRING(@Name, 2, 49))
                END

            -- Apostrophes
            SELECT @NameCamelCase = 
                CASE 
                    WHEN @NameCamelCase LIKE '%''%'
                        THEN SUBSTRING(@NameCamelCase, 1, CHARINDEX('''', @NameCamelCase) - 1) + ''''  + UPPER(SUBSTRING(@NameCamelCase, CHARINDEX('''', @NameCamelCase) + 1, 1)) + SUBSTRING(@NameCamelCase, CHARINDEX('''', @NameCamelCase) + 2, 50)
                    ELSE
                        @NameCamelCase
                END 


            -- Hyphenated names (do it twice to account for double hyphens)
            SELECT @NameCamelCase = 
                CASE 
                    WHEN @NameCamelCase LIKE '%-%'
                        THEN SUBSTRING(@NameCamelCase, 1, CHARINDEX('-', @NameCamelCase) - 1) + '^'  + UPPER(SUBSTRING(@NameCamelCase, CHARINDEX('-', @NameCamelCase) + 1, 1)) + SUBSTRING(@NameCamelCase, CHARINDEX('-', @NameCamelCase) + 2, 50)
                    ELSE
                        @NameCamelCase
                END 

            SELECT @NameCamelCase = 
                CASE 
                    WHEN @NameCamelCase LIKE '%-%'
                        THEN SUBSTRING(@NameCamelCase, 1, CHARINDEX('-', @NameCamelCase) - 1) + '^'  + UPPER(SUBSTRING(@NameCamelCase, CHARINDEX('-', @NameCamelCase) + 1, 1)) + SUBSTRING(@NameCamelCase, CHARINDEX('-', @NameCamelCase) + 2, 50)
                    ELSE
                        @NameCamelCase
                END 

            SELECT @NameCamelCase = REPLACE(@NameCamelCase, '^', '-')

            -- Multiple word names (do it twice to account for three word names)
            SELECT @NameCamelCase = 
                CASE 
                    WHEN @NameCamelCase LIKE '% %'
                        THEN SUBSTRING(@NameCamelCase, 1, CHARINDEX(' ', @NameCamelCase) - 1) + '?'  + UPPER(SUBSTRING(@NameCamelCase, CHARINDEX(' ', @NameCamelCase) + 1, 1)) + SUBSTRING(@NameCamelCase, CHARINDEX(' ', @NameCamelCase) + 2, 50)
                    ELSE
                        @NameCamelCase
                END 

            SELECT @NameCamelCase = 
                CASE 
                    WHEN @NameCamelCase LIKE '% %'
                        THEN SUBSTRING(@NameCamelCase, 1, CHARINDEX(' ', @NameCamelCase) - 1) + '?'  + UPPER(SUBSTRING(@NameCamelCase, CHARINDEX(' ', @NameCamelCase) + 1, 1)) + SUBSTRING(@NameCamelCase, CHARINDEX(' ', @NameCamelCase) + 2, 50)
                    ELSE
                        @NameCamelCase
                END 

            SELECT @NameCamelCase = REPLACE(@NameCamelCase, '?', ' ')

            -- Names in Parentheses         
            SELECT @NameCamelCase = 
                CASE 
                    WHEN @NameCamelCase LIKE '%(%'
                        THEN SUBSTRING(@NameCamelCase, 1, CHARINDEX('(', @NameCamelCase) - 1) + '('  + UPPER(SUBSTRING(@NameCamelCase, CHARINDEX('(', @NameCamelCase) + 1, 1)) + SUBSTRING(@NameCamelCase, CHARINDEX('(', @NameCamelCase) + 2, 50)
                    ELSE
                        @NameCamelCase
                END 


            SELECT @NameCamelCase = REPLACE(@NameCamelCase, ' sr', ' Sr')           
            SELECT @NameCamelCase = REPLACE(@NameCamelCase, ' jr', ' Jr')           
            SELECT @NameCamelCase = REPLACE(@NameCamelCase, ' ii', ' II')
            SELECT @NameCamelCase = REPLACE(@NameCamelCase, ' iii', ' III')
            SELECT @NameCamelCase = REPLACE(@NameCamelCase, ' DE ', ' de ')
            SELECT @NameCamelCase = REPLACE(@NameCamelCase, 'macdonald', 'MacDonald')

            if (@NameCamelCase LIKE '% iv')
                SELECT @NameCamelCase = REPLACE(@NameCamelCase, ' iv', ' IV')

            if ((@NameCamelCase = 'i') or (@NameCamelCase = 'ii') or (@NameCamelCase = 'iii') or (@NameCamelCase = 'iv'))
                SELECT @NameCamelCase = UPPER(@NameCamelCase)

            -- Return the result of the function
            RETURN ISNULL(@NameCamelCase, '')

        END

    RETURN ISNULL(@NameCamelCase, '')

END
0 голосов
/ 09 января 2014

Вот простая вещь, не усложняйте.

Oracle: ВЫБЕРИТЕ initcap (нижний («Это МОЁ стремление к конвертации») ОТ двойного;

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...