2009-05-07 5 views
3

Ich habe eine Tabelle mit einer Spalte, deren Werte von einer Enumeration stammen. Ich muss eine TSQL-Funktion erstellen, um diese Werte beim Abruf in "Friendly Names" zu konvertieren.PascalCase-Zeichenfolge in "Freundlicher Name" in TSQL konvertieren

Beispiele:

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

Ich brauche eine gerade TSQL UDF Lösung. Ich habe keine Möglichkeit, Extended Store-Prozeduren oder CLR-Code zu installieren.

+1

+1 nur mit diesem Problem fertig zu werden für zu haben! – Joseph

Antwort

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

nach SUBSTRING Hinzufügen des zusätzlichen Platz zu entfernen, es funktioniert wie ein Zauber Danke ! –

+2

Nur ein kleiner Vorschlag: statt der letzten return SUBSTRING (@ PascalName, 2, LEN (@PascalName)) --remove Raum am Anfang Sie return LTrim (@PascalName) machen hat verwendet haben, konnte nicht ein großer Unterschied in _this_ Fall, aber im allgemeinen entfernt sie führende Leerzeichen (unabhängig davon, wie viele sie sind), aber nicht entfernt anderen eventuellen Charakter differente als Raum –

+0

@Turro -.. großer Tipp, den ich damals nicht daran gedacht habe , aber jetzt aktualisiert. Vielen Dank! –

1

Wenn Sie SQL Server 2005 verwenden, können Sie eine native CLR-Prozedur schreiben:

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

Ausgänge:

Convert My Crazy Pascal Fall Satz Freundlich Fall

Wenn Sie nicht mit 2005 verwenden, dann müssen Sie entweder manuell analysieren oder regex-Objekt mit Hilfe von extend referenzieren ed Prozeduren. Ein guter Artikel finden Sie hier:

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

Edit: Eine UDF die Datenbank nicht beeinflussen können, so dass Sie nicht die Regex COM-Objekt registrieren können, so dass diese Idee austreibt. Eine gespeicherte Prozedur kann jedoch - so könnte das eine Route sein.

Um eine Groß-und Kleinschreibung zu beachten, müssen Sie die Sortierung für die Abfrage Groß-und Kleinschreibung beachten, und dann einen Ersatz verwenden, denke ich ... hier ist ein Artikel, der hilfreich sein kann Sie in die richtige Richtung:

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

+0

Ich brauche eine direkte TSQL UDF. Eine CLR-Funktion ist für mich keine Option. –

+0

Hmm, ekelhaft, ich bin mir nicht sicher, ob dies mit einer UDF möglich ist ... weil eine UDF die Datenbank nicht beeinflussen kann, so dass Sie die Regex-Bibliothek nicht registrieren können.Sie müssten dies über einen gespeicherten Proc tun. Ich bin mir ziemlich sicher, dass Sie es manuell analysieren müssen. – BenAlabaster

+0

Dies wird zu XML in X M L slipt. :/ Ich würde vorschlagen:??? 'New Regex ( @“ (<= [AZ]) (= [AZ] [az]) | (<= [^ AZ]) (= [AZ]) | (? <= [A-Za-z]) (? = [^ 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 
 

ändern Sie den Wert von @arg zu etwas, möchten Sie mit testen.

Sie müssen möglicherweise auch die @ output-Deklaration ändern, um eine Zeichenfolge aufzunehmen, die dieselbe Länge wie die @arg + -Zahl von Leerzeichen hat, die sie möglicherweise benötigt. Ich habe es in meinem Beispiel verdoppelt.

+0

@Shahkalpesh - Es gibt einen Syntaxfehler auf der Linie mit: (@currentCharASCII> = 65 und @currentCharASCII @argLen) –

+0

ich es auch getestet. Es kompiliert nicht. -1 – ichiban

+0

SO aß <= sign. Ich formatierte den Beitrag erneut. Es sollte jetzt OK sein. – shahkalpesh

1

nicht die eleganteste Lösung, aber es funktioniert:

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

Dieser Code kompiliert nicht in SQL Server. Ich nehme an, das ist entweder PLSQL oder MySQL. –

+0

Ich denke, dieser Code sollte funktionieren. Machen Sie es TSQL-konform und ich gebe Ihnen eine Upvote. – ichiban

+0

Bei weiterer Überprüfung habe ich festgestellt, dass die Syntax unter SQL Server 2008 funktioniert, aber für ältere Versionen fehlschlägt. Dennoch. +1 –

0

Ich fand dies genau nach Bedarf arbeitet. Mit freundlicher Genehmigung von 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 

Verbrauch:

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

Ausgang:

This Function Will Convert This String To Title Case!