2011-03-02 21 views
8

no quiero crear función personalizada para que si hay alguna ya existe en SQL Server¿Hay alguna función incorporada de SQL Server para convertir cadenas en camel case?

Cadena de entrada: This is my string to convert
Resultados previstos: This Is My String To Convert

+1

Técnicamente, eso sería PascalCase. – Thomas

+3

@thomas, técnicamente no es ninguna de las dos cosas, es solo una cadena de palabras en mayúscula –

+0

@nathan gonzalez - Estoy corregido. – Thomas

Respuesta

6

yo sepa, SQL Server no tiene ninguna función incorporada para esto.
Tiene que escribir una función personalizada para ello.

Pruebe esto.

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 

Salida:

Input String : 'microSoft sql server' 
Output String : 'Microsoft Sql Server' 
+0

Bueno, pero solo maneja espacios como delimitadores. No manejará Dashes/Hyphens por ejemplo, pero aún así responde la pregunta. Tampoco maneja NULL, devuelve una cadena vacía en su lugar. – MikeTeeVee

+0

Tampoco maneja cadenas de una sola letra (es decir, Primeros apellidos intermedios como cadenas separadas): dbo.CamelCase (p.FirstName), dbo.CamelCase (p.LastName), dbo.CamelCase (p.MiddleName) – mmv1219

21
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 
6

me tendría que ir con "No, eso no existe". Esto se basa en varios años de examinar las funciones de cadena disponibles en T-SQL y algunos cursos de 5 días muy recientes en SQL Server 2008 R2.

Por supuesto, todavía podría estar equivocado :).

2

mi estrategia

  • Si el nombre ya está en mayúsculas y minúsculas, la confianza de que es lo correcto.
  • Si el nombre no está en mayúsculas y minúsculas, a continuación, hacer lo siguiente:
  • Recorte el nombre de eliminar el espacio en blanco
  • cuenta de los nombres que comienzan con “Mc” como “McDavid”
  • cuenta para nombres con apóstrofes como O'Reilly
  • cuenta de los nombres con guión (nombres de casada) “Anderson-Johnson”
  • cuenta para múltiples nombres de palabras como “la Russa”
  • Asegúrese de que los sufijos incluidas en el campo de nombres se capitalizan adecuadamente

El Código

Aquí está mi post original en esto: Converting String to Camel Case in 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

Me gusta donde vas con esto Sin embargo, este código no se ejecutó en SQL Server 2008 R2. Los errores fueron "Debe declarar la variable escalar" @NameCamelCase ".". –

+0

Gracias. Estaba tratando de hacerlo un poco más simple y extrañé algunas cosas. Actualizando ahora ... – Narnian

2

Si el objetivo de la operación es embellecer las cadenas de nombres a continuación, la capitalización adecuada se podría definir como la primera letra de cada palabra separada por caracteres no alfabéticos.

Otras soluciones no tienen en cuenta:

  1. Preservar de espaciamiento (especialmente los espacios finales).
  2. Preservar NULL, cadena vacía o una cadena de espacios.
  3. Gestionar más que espacios (por ejemplo, guiones, comas, guiones bajos, etc.)
  4. Gestionar más de un carácter no alfa entre palabras/tokens.
  5. Manejo de excepciones (por ejemplo, McDonald o III como en "James William Bottomtooth the III").

Nota: Mi solución no admite excepciones.
Si está muy preocupado por eso, entonces le sugiero que escriba un ensamblado CLR C# para ellos, ya que será complicado, y las cadenas son un área donde C# sobresale.
Otra solución aquí trata de dar cuenta de esto, pero aún tomaría "ivan terrible el iv" y la salida "** IV *** un Terrible The IV *".

Ésta es la función que se me ocurrió:

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 


Usted lo llamaría así:

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


La salida tendrá el siguiente aspecto:

PascalCase Output

-3

Aquí hay algo simple, no lo compliques.

Oracle: SELECCIONAR initcap (inferior ('Esta es MI advertencia a CONVERT')) DESDE dual;

+1

La pregunta es sobre sqlserver no oráculo. – Nezam

Cuestiones relacionadas