2009-05-07 3 views
3

J'ai une table avec une colonne dont les valeurs proviennent d'une énumération. J'ai besoin de créer une fonction TSQL pour convertir ces valeurs en "noms conviviaux" lors de la récupération.Conversion de la chaîne PascalCase en "Nom convivial" dans TSQL

Exemples:

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

je besoin d'une solution UDF TSQL droite. Je n'ai pas la possibilité d'installer des procédures de magasin étendu ou du code CLR.

+1

+1 juste pour avoir à faire face à ce problème! – Joseph

Répondre

2
/* 
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 
+0

Après avoir ajouté SUBSTRING pour supprimer l'espace supplémentaire, cela fonctionne comme un charme. ! –

+2

Juste une petite suggestion: au lieu du retour finale SUBSTRING (@ PascalName, 2, LEN (@PascalName)) espace remove au début vous auriez pu utiliser retour LTrim (@PascalName) ne fait pas grande différence dans ce cas, mais en général il supprime les espaces de premier plan (indépendamment du nombre de ceux-ci) mais ne supprime aucun autre caractère éventuel différent de l'espace –

+0

@Turro - Bon conseil, je n'y avais pas pensé à l'époque , mais mis à jour maintenant. Merci! –

1

Si vous utilisez SQL Server 2005, vous pouvez écrire une procédure CLR natif:

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

Sorties:

Convertir My Crazy Pascal Case Sentence Friendly Case

Si vous êtes et non en utilisant 2005, alors vous devez soit l'analyser manuellement ou référencer l'objet regex en utilisant étendre procédures ed. Un bon article se trouve ici:

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

Edit: Une UDF ne peut pas affecter la base de données, de sorte que vous ne pouvez pas enregistrer l'objet regex com, de sorte que jette cette idée sur. Une procédure stockée cependant, peut - ce qui pourrait être un itinéraire. Pour faire une comparaison sensible à la casse, vous devez définir le classement pour que la requête soit sensible à la casse, puis utiliser un remplacement je pense ... voici un article qui pourrait être utile pour pointer vous dans la direction droite:

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

+0

Je dois utiliser un UDF TSQL droit. Une fonction CLR n'est pas une option pour moi. –

+0

Hmm, méchant, je ne suis pas sûr si cela peut être fait en utilisant un UDF ... car un UDF ne peut pas affecter la base de données, donc vous ne pouvez pas enregistrer la bibliothèque regex.Vous auriez à le faire à travers un proc stocké. Je suis sûr que vous devrez l'analyser manuellement. – BenAlabaster

+0

Cela va également faire glisser XML dans X M L. :/ Je suggérerais: 'new Regex ( @" (? <= [AZ]) (? = [AZ] [az]) | (? <= [^ AZ]) (? = [AZ]) | (? <= [A-Za-z]) ", RegexOptions.IgnorePatternWhitespace' – Custodio

1
 

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 
 

Modifiez la valeur de @arg à quelque chose, vous voulez tester avec.

De même, vous devrez peut-être modifier la déclaration @output pour accepter une chaîne ayant la même longueur que le nombre d'espaces @arg + dont elle pourrait avoir besoin. Je l'ai doublé dans mon exemple.

+0

@Shahkalpesh - Il y a une erreur de syntaxe sur la ligne avec: (@currentCharASCII> = 65 et @currentCharASCII @argLen) –

+0

Je l'ai aussi testé. Il ne compile pas. -1 – ichiban

+0

SO ate le signe <=. J'ai reformaté le message. Ça devrait être OK maintenant. – shahkalpesh

1

pas la solution la plus élégante, mais cela fonctionne:

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

Ce code ne compile pas dans SQL Server. Je suppose que c'est PLSQL ou MySQL. –

+0

Je pense que ce code devrait fonctionner. Rendez-le compatible TSQL et je vous donnerai un upvote. – ichiban

+0

Après une inspection plus poussée, j'ai trouvé que la syntaxe fonctionne sous SQL Server 2008, mais elle échoue pour les anciennes versions. Néanmoins. +1 –

0

Je trouve cela fonctionne exactement comme nécessaire. Avec l'aimable autorisation 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 

Utilisation:

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

Sortie:

This Function Will Convert This String To Title Case! 
Questions connexes