【问题标题】:Converting PascalCase string to "Friendly Name" in TSQL在 SQL 中将 Pascal Case 字符串转换为“友好名称”
【发布时间】:2010-10-24 15:44:26
【问题描述】:

我有一个表,其中有一列的值来自枚举。我需要创建一个 TSQL 函数,以便在检索时将这些值转换为“友好名称”。

示例:

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

我需要一个直接的 TSQL UDF 解决方案。我没有安装扩展存储过程或 CLR 代码的选项。

【问题讨论】:

  • +1 只是为了解决这个问题!

标签: sql-server tsql user-defined-functions


【解决方案1】:
/*
 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

【讨论】:

  • 添加 SUBSTRING 删除多余的空间后,它就像一个魅力。谢谢!
  • 只是一个小建议:而不是最终的 return SUBSTRING(@PascalName,2,LEN(@PascalName)) --remove space at the beginning you could have used return LTrim(@PascalName) 不在 this 的情况下有很大的不同,但一般来说,它会删除前导空格(不管它们有多少),但不会删除与空格不同的任何其他最终字符。
  • @Turro - 很棒的提示。当时没想到,现在更新了。谢谢!
【解决方案2】:

如果您使用的是 SQL Server 2005,则可以编写本机 CLR 过程:

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

输出:

将我的疯狂帕斯卡案例句子转换为友好案例

如果您使用 2005,那么您必须手动解析它或使用扩展过程引用正则表达式对象。一篇好文章可以在这里找到:

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

编辑: UDF 不能影响数据库,因此您不能注册正则表达式 com 对象,这样就放弃了这个想法。但是,存储过程可以 - 所以这可能是一条路线。

为了进行区分大小写的比较,您必须将查询的排序规则设置为区分大小写,然后使用我认为的替换...这是一篇可能有助于指出您的文章朝着正确的方向前进:

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

【讨论】:

  • 我需要使用直接的 TSQL UDF。 CLR 函数不适合我。
  • 嗯,讨厌,我不确定它是否可以使用 UDF 来完成......因为 UDF 不能影响数据库,所以你不能注册正则表达式库。您必须通过存储过程来完成。我很确定你必须手动解析它。
  • 这也会在 X M L 中滑动 XML。 :/ 我建议:new Regex( @" (?&lt;=[A-Z])(?=[A-Z][a-z]) | (?&lt;=[^A-Z])(?=[A-Z]) | (?&lt;=[A-Za-z])(?=[^A-Za-z])", RegexOptions.IgnorePatternWhitespace
【解决方案3】:

不是最优雅的解决方案,但它有效:

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

【讨论】:

  • 此代码无法在 SQL Server 中编译。我假设这是 PLSQL 或 MySQL。
  • 我认为这段代码应该可以工作。让它符合 TSQL,我会给你一个赞成票。
  • 经过进一步检查,我发现该语法在 SQL Server 2008 下有效,但对于旧版本则失败。尽管如此。 +1
【解决方案4】:
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 + 可能需要的空格数相同的字符串。在我的例子中,我把它翻了一番。

【讨论】:

  • @Shahkalpesh - 存在语法错误:(@currentCharASCII >= 65 and @currentCharASCII @argLen)
  • 我也测试过。它不编译。 -1
  • 所以吃了
【解决方案5】:

我发现这完全符合要求。致谢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!

【讨论】:

    猜你喜欢
    • 2011-05-03
    • 2023-03-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-09-12
    • 1970-01-01
    相关资源
    最近更新 更多