2009-05-07 5 views
3

У меня есть таблица со столбцом, значения которого взяты из перечисления. Мне нужно создать функцию TSQL для преобразования этих значений в «Friendly Names» после извлечения.Преобразование строки PascalCase в «Friendly Name» в TSQL

Примеры:

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

мне нужен прямой решение TSQL UDF. У меня нет возможности устанавливать расширенные процедуры хранения или код CLR.

+1

+1 только для того, чтобы справиться с этой проблемой! – Joseph

ответ

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

После добавления SUBSTRING, чтобы удалить лишнее пространство, оно работает как шарм. ! –

+2

Просто немного предложения: вместо окончательного возвращение SUBSTRING (@ PascalName, 2, LEN (@PascalName)) --remove пространства в начале вы могли бы использовать обратного LTRIM (@PascalName) не делает большая разница в этом деле, но в целом он удаляет ведущие пробелы (независимо от того, сколько они есть), но не удаляет другой возможный символ, отличный от пробела. –

+0

@Turro - отличный совет. В то время я не думал об этом , но обновил его сейчас. Спасибо! –

1

Если вы используете SQL Server 2005, вы можете написать нативную процедуру CLR:

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

Выходы:

верстку Сумасшедшая Pascal Case ПРИГОВОР Дружественные Case

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

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

Edit: UDF не может повлиять на базу данных, так что вы не можете зарегистрировать регулярное выражение COM-объекта, так что ставит эту идею из. Однако хранимая процедура может - так что это может быть маршрут.

Для того, чтобы сделать сравнение, чувствительное к регистру, вам нужно будет установить сопоставление для запроса чувствительным к регистру, а затем использовать замену, я думаю ... вот статья, которая может быть полезна при указании вы в правильном направлении:

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

+0

Мне нужно использовать прямой TSQL UDF. Функция CLR для меня не является вариантом. –

+0

Хмм, противно, я не уверен, что это можно сделать с помощью UDF ... потому что UDF не может повлиять на базу данных, поэтому вы не можете зарегистрировать библиотеку регулярных выражений.Вы должны сделать это через хранимую процедуру. Я уверен, что вам придется разобрать его вручную. – BenAlabaster

+0

Это также приведет к сокращению XML в X M L. :/ Я предлагаю: '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 
 

Изменить значение @arg к чему-то, вы хотите проверить с.

Кроме того, вам может потребоваться изменить объявление @output для размещения строки, которая имеет ту же длину, что и число @arg +, которое может потребоваться. Я удвоил его в своем примере.

+0

@Shahkalpesh - В строке есть синтаксическая ошибка: (@currentCharASCII> = 65 и @currentCharASCII @argLen) –

+0

Я тоже ее протестировал. Он не компилируется. -1 – ichiban

+0

SO ate <= sign. Я отформатировал сообщение снова. Теперь все должно быть хорошо. – shahkalpesh

1

Не самое элегантное решение, но оно работает:

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

Этот код не компилируется в SQL Server. Я предполагаю, что это либо PLSQL, либо MySQL. –

+0

Я думаю, что этот код должен работать. Сделайте его TSQL совместимым, и я дам вам преимущество. – ichiban

+0

После дополнительной проверки я обнаружил, что синтаксис работает под SQL Server 2008, но он не подходит для более старых версий. Тем не менее. +1 –

0

Я нашел, что это работает точно так же, как требуется. Предоставлено 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 

Использование:

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

Выход:

This Function Will Convert This String To Title Case! 
Смежные вопросы