Pregunta

Tengo una tabla con una columna cuyos valores provienen de una enumeración. Necesito crear una función TSQL para convertir estos valores a '' Nombres amigables '' al recuperarlo.

Ejemplos:

 'DateOfBirth' --> 'Date Of Birth'
 'PrincipalStreetAddress' --> 'Principal Street Address'

Necesito una solución directa de TSQL UDF. No tengo la opción de instalar procedimientos de almacenamiento extendido o código CLR.

¿Fue útil?

Solución

/*
 Try this.  It's a first hack - still has problem of adding extra space
 at start if first char is in upper case.
*/
create function udf_FriendlyName(@PascalName varchar(max))
returns varchar(max)
as
begin

    declare @char char(1)
    set @char = 'A'

    -- Loop through the letters A - Z, replace them with a space and the letter
    while ascii(@char) <= ascii('Z')
    begin
        set @PascalName = replace(@PascalName, @char collate Latin1_General_CS_AS, ' ' + @char) 
        set @char = char(ascii(@char) + 1)
    end

    return LTRIM(@PascalName) --remove extra space at the beginning

end

Otros consejos

Si está utilizando SQL Server 2005, puede escribir un procedimiento CLR nativo:

static string ToFriendlyCase(this string PascalString)
{
    return Regex.Replace(PascalString, "(?!^)([A-Z])", " $1");
}

Salidas:

  

Convierta mi oración de caso Crazy Pascal en un caso amistoso

Si no usa 2005, debe analizarlo manualmente o hacer referencia al objeto regex mediante procedimientos extendidos. Puede encontrar un buen artículo aquí:

http://www.codeproject.com/KB/mcpp/xpregex.aspx

Editar: un UDF no puede afectar la base de datos, por lo que no puede registrar el objeto regex com, por lo que arroja esa idea. Sin embargo, un procedimiento almacenado puede, por lo que podría ser una ruta.

Para hacer una comparación entre mayúsculas y minúsculas, tendrá que establecer la intercalación para que la consulta sea sensible a mayúsculas y minúsculas, creo que ... aquí hay un artículo que podría ser útil para señalarle fuera en la dirección correcta:

http://www.mssqltips.com/tip.asp?tip=1032

No es la solución más elegante, pero funciona:

declare @pascalCasedString nvarchar(max) = 'PascalCasedString'
declare @friendlyName nvarchar(max) = ''
declare @currentCode int;
declare @currentChar nvarchar;

while (LEN(@pascalCasedString) > 0)
    begin
        set @currentCode = UNICODE(@pascalCasedString)
        set @currentChar = NCHAR(@currentCode)

        if ((@currentCode >= 65) AND (@currentCode <= 90))
        begin
            set @friendlyName += SPACE(1)
        end
        set @friendlyName +=  @currentChar
        set @pascalCasedString = RIGHT(@pascalCasedString,LEN(@pascalCasedString) - 1)
    end

select @friendlyName

declare @arg varchar(20)
set @arg = 'DateOfBirthOnMonday'

declare @argLen int
set @argLen = len(@arg)

declare @output varchar(40)
set @output = ''

declare @i int
set @i = 1

declare @currentChar varchar(1)
declare @currentCharASCII int

while (1 = 1)
begin
set @currentChar = substring(@arg, @i, 1)
set @currentCharASCII = ascii(@currentChar)

if (@currentCharASCII >= 65 and @currentCharASCII <= 90)
set @output = @output + ' ' 

set @output = @output + @currentChar

set @i = @i+ 1

if (@i > @argLen) break
end

set @output = ltrim(rtrim(@output))
print @output

Cambia el valor de @arg a algo con lo que quieras probar.

Además, es posible que deba cambiar la declaración @output para acomodar una cadena que tenga la misma longitud que el número de espacios @arg + que pueda necesitar. Lo he duplicado en mi ejemplo.

Encontré que esto funciona exactamente como se requiere. Cortesía de SqlAuthority.com :

CREATE FUNCTION dbo.udf_TitleCase (@InputString VARCHAR(4000) )
RETURNS VARCHAR(4000)
AS
BEGIN
DECLARE @Index INT
DECLARE @Char CHAR(1)
DECLARE @OutputString VARCHAR(255)
SET @OutputString = LOWER(@InputString)
SET @Index = 2
SET @OutputString =
STUFF(@OutputString, 1, 1,UPPER(SUBSTRING(@InputString,1,1)))
WHILE @Index <= LEN(@InputString)
BEGIN
SET @Char = SUBSTRING(@InputString, @Index, 1)
IF @Char IN (' ', ';', ':', '!', '?', ',', '.', '_', '-', '/', '&','''','(')
IF @Index + 1 <= LEN(@InputString)
BEGIN
IF @Char != ''''
OR
UPPER(SUBSTRING(@InputString, @Index + 1, 1)) != 'S'
SET @OutputString =
STUFF(@OutputString, @Index + 1, 1,UPPER(SUBSTRING(@InputString, @Index + 1, 1)))
END
SET @Index = @Index + 1
END
RETURN ISNULL(@OutputString,'')
END

Uso:

SELECT dbo.udf_TitleCase('This function will convert this string to title case!')

Salida:

This Function Will Convert This String To Title Case!
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top