SQL Query:如何将列名拆分为多个(regexp?)

时间:2010-11-17 19:51:30

标签: sql sql-server sql-server-2005 sql-server-2008 stored-procedures

我有一个包含许多列的表。所有列(属性)都使用相同的命名约定命名:thisIsColumnName,thisIsAttributeName,thisIsAlsoColumnName等。我想创建一个查询(可能使用information_schema.columns表),它将所有这些名称分成几部分并生成一个包含的列表所有列名称的不同部分:

thisIsColumnName
thisIsAttributeName

产生

this
Is
Column
Attribute
Name

如何使用T-SQL为表中的所有列(以及数据库中的所有表)执行此操作?有什么想法吗?

2 个答案:

答案 0 :(得分:1)

一种方法是编写一个CLR用户定义函数,为您完成。这是一个例子,我采取像“ThisIsAColumnName”这样的东西并发出“这是一个列名”

public static String SplitCamel( String input ) {
    return System.Text.RegularExpressions.Regex.Replace(input, "([A-Z][A-Z]*)", " $1", System.Text.RegularExpressions.RegexOptions.Compiled).Trim();
} // method::SplitCamel

有关详细信息,请参阅此处: http://msdn.microsoft.com/en-us/library/w2kae45k(VS.80).aspx

答案 1 :(得分:0)

由于@Chris Lively表明某种形式的稳定骆驼分裂函数可能是最好的方法,但是这里有一个查询可以全部内联。对于模式匹配,校对显然是一个考虑因素,在这种情况下,我在PATINDEX函数中使用了一个区分大小写(旁边我必须明确定义匹配表达式中的每个大写字母,因为[AZ]没有返回正确的结果,我认为这是another question的主题....)

CREATE TABLE dbo.OriginalNames 
(
    CamelCaseName        VARCHAR(30),    
)
GO

INSERT INTO dbo.OriginalNames VALUES ('thisIsColumnName')
INSERT INTO dbo.OriginalNames VALUES ('thisIsAttributeName')
INSERT INTO dbo.OriginalNames VALUES ('thisIsAnotherAttributeName')

GO

SELECT * FROM dbo.OriginalNames;
GO

WITH
L0 AS(SELECT 1 AS c UNION ALL SELECT 1),
L1 AS(SELECT 1 AS c FROM L0 AS A, L0 AS B),
L2 AS(SELECT 1 AS c FROM L1 AS A, L1 AS B),
L3 AS(SELECT 1 AS c FROM L2 AS A, L2 AS B),
Numbers AS(SELECT ROW_NUMBER() OVER(ORDER BY c) AS n FROM L3)
SELECT DISTINCT(SplitNames.Value)
FROM (
SELECT  nums.n, names.CamelCaseName, LTRIM(RTRIM(SUBSTRING(names.CamelCaseName, nums.n - 1, PATINDEX('%[|ABCDEFGHIJKLMNOPQRSTUVWXYZ]%', SUBSTRING(names.CamelCaseName + N'|', nums.n, LEN(names.CamelCaseName)) COLLATE SQL_Latin1_General_Cp1_CS_AS)))) AS [Value]
 FROM   Numbers AS nums INNER JOIN dbo.OriginalNames AS names ON nums.n <= CONVERT(int, LEN(names.CamelCaseName) + 1) AND PATINDEX('%[|ABCDEFGHIJKLMNOPQRSTUVWXYZ]%', SUBSTRING(N'|' + names.CamelCaseName, nums.n, 1) COLLATE SQL_Latin1_General_Cp1_CS_AS) > 0) AS SplitNames

GO

--DROP TABLE dbo.OriginalNames

-- OUTPUT as follows
--
-- Value
-- =========
-- Another
-- Attribute
-- Column
-- Is
-- Name
-- this