SQL Server自定义提取中文,简体中文,英文,数字函数汇总
在日常的数据库开发工作中,我们经常遇到需要从混杂的字符串中提取特定类型字符的场景。比如从地址中提取中文、从订单号中提取数字、从用户输入中过滤出英文等。今天给大家分享一套实用的SQL Server自定义函数,帮助您轻松应对这些需求。
dbo.getCN这个函数利用Unicode编码范围(19968-40869)来识别中文字符,支持繁简体中文。
CREATE FUNCTION dbo.getCN( @str AS NVARCHAR(4000))RETURNS NVARCHAR(4000)ASBEGIN DECLARE @word NCHAR(1), @CN NVARCHAR(4000) SET @CN = '' WHILE LEN(@str) > 0 BEGIN SET @word = LEFT(@str, 1) -- Unicode中文字符范围:19968到40869 IF UNICODE(@word) BETWEEN 19968 AND 19968 + 20901 SET @CN = @CN + @word SET @str = RIGHT(@str, LEN(@str) - 1) END RETURN @CNENDGO
PRINT dbo.getCN('ASDKG论坛KDL')-- 结果:论坛PRINT dbo.getCN('ASDKG論壇KDL')-- 结果:論壇PRINT dbo.getCN('ASDKDL')-- 结果:(空)
dbo.getNumber使用PATINDEX配合正则表达式模式,过滤掉所有非数字字符。
CREATE FUNCTION dbo.getNumber(@S VARCHAR(100))RETURNS VARCHAR(100)ASBEGIN WHILE PATINDEX('%[^0-9]%', @S) > 0 BEGIN SET @S = STUFF(@S, PATINDEX('%[^0-9]%', @S), 1, '') END RETURN @SENDGO
PRINT dbo.getNumber('呵呵ABC123ABC')-- 结果:123
如果需要保留逗号、星号等其他字符,可以在模式中添加:
-- 保留数字、逗号和星号PATINDEX('%[^0-9,*]%', @S) > 0
dbo.getEn提取字符串中的大小写英文字母(a-z)。
CREATE FUNCTION dbo.getEn(@S VARCHAR(100))RETURNS VARCHAR(100)ASBEGIN WHILE PATINDEX('%[^a-z]%', @S) > 0 BEGIN SET @S = STUFF(@S, PATINDEX('%[^a-z]%', @S), 1, '') END RETURN @SENDGO
PRINT dbo.getEn('呵呵ABC123ABC')-- 结果:ABCABC
dbo.getSimplifiedCN通过"吖-座"这个汉字范围来匹配简体中文字符。
CREATE FUNCTION dbo.getSimplifiedCN(@S NVARCHAR(100))RETURNS VARCHAR(100)ASBEGIN WHILE PATINDEX('%[^吖-座]%', @S) > 0 SET @S = STUFF(@S, PATINDEX('%[^吖-座]%', @S), 1, N'') RETURN @SENDGO
PRINT dbo.getSimplifiedCN('呵呵ABC123ABC')-- 结果:呵呵
dbo.distinct_str适用于处理以特定分隔符连接的字符串,去重后保留原有顺序。
CREATE FUNCTION dbo.distinct_str(@S NVARCHAR(100), @SPLIT VARCHAR(50))RETURNS VARCHAR(100)ASBEGIN IF @S IS NULL RETURN(NULL) DECLARE @NEW VARCHAR(50), @INDEX INT, @TEMP VARCHAR(50) -- 确保字符串首尾都有分隔符 IF LEFT(@S, 1) <> @SPLIT SET @S = @SPLIT + @S IF RIGHT(@S, 1) <> @SPLIT SET @S = @S + @SPLIT WHILE CHARINDEX(@SPLIT, @S) > 0 AND LEN(@S) <> 1 BEGIN SET @INDEX = CHARINDEX(@SPLIT, @S) SET @TEMP = LEFT(@S, CHARINDEX(@SPLIT, @S, @INDEX + LEN(@SPLIT))) IF @NEW IS NULL SET @NEW = ISNULL(@NEW, '') + @TEMP ELSE SET @NEW = ISNULL(@NEW, '') + REPLACE(@TEMP, @SPLIT, '') + @SPLIT -- 删除所有重复项 WHILE CHARINDEX(@TEMP, @S) > 0 BEGIN SET @S = STUFF(@S, CHARINDEX(@TEMP, @S) + LEN(@SPLIT), CHARINDEX(@SPLIT, @S, CHARINDEX(@TEMP, @S) + LEN(@SPLIT)) - CHARINDEX(@TEMP, @S), '') END END RETURN RIGHT(LEFT(@NEW, LEN(@NEW) - 1), LEN(LEFT(@NEW, LEN(@NEW) - 1)) - 1)ENDGO
PRINT dbo.distinct_str('A,A,B,C,C,B,C,', ',')-- 结果:A,B,C
PRINT dbo.distinct_str2('AABCCD')-- 结果:ABCD
数据清洗:从脏数据中提取有效信息
地址解析:分离省市县等中文信息和门牌号等数字信息
用户输入处理:过滤特殊字符,只保留需要的字符类型
数据去重:处理标签、分类等重复项
对于大数据量的处理,建议使用CLR函数替代标量函数
可以考虑将这些函数改写成内联表值函数
在调用时注意数据类型匹配,避免隐式转换
这些自定义函数虽然简单,但在日常开发中却非常实用。您可以根据实际需求进行修改和扩展,比如添加对大小写英文的支持、提取特定范围内的数字等。
阅读原文:原文链接