如何用正则表达式在指定存储过程中统计多个特定单词的出现次数
解决SQL存储过程中多单词出现次数统计问题
原代码的问题
- 变量赋值语法错误:
set @word = (michael|Kuldeep)不符合SQL字符串赋值规则,且SQL的LIKE运算符不支持这种正则风格的|或逻辑。 - 统计逻辑错误:
michael(7字符)和Kuldeep(6字符)长度不同,用统一的len(@word)计算次数会导致结果偏差,无法得到准确的总次数。
方案1:SQL Server 2017+ 内置正则函数实现
SQL Server 2017及以上版本支持REGEXP_LIKE和REGEXP_REPLACE等正则函数,可结合传统长度差法分别统计每个单词的次数,再求和:
DECLARE @proc_name NVARCHAR(128) = 'MenuDetailsSelect'; SELECT name, -- 统计michael出现次数 (LEN(object_definition(object_id)) - LEN(REPLACE(object_definition(object_id), 'michael', ''))) / LEN('michael') AS michael_count, -- 统计Kuldeep出现次数 (LEN(object_definition(object_id)) - LEN(REPLACE(object_definition(object_id), 'Kuldeep', ''))) / LEN('Kuldeep') AS kuldeep_count, -- 总次数 (LEN(object_definition(object_id)) - LEN(REPLACE(object_definition(object_id), 'michael', ''))) / LEN('michael') + (LEN(object_definition(object_id)) - LEN(REPLACE(object_definition(object_id), 'Kuldeep', ''))) / LEN('Kuldeep') AS total_count FROM sys.procedures WHERE name = @proc_name AND type = 'P' -- 用正则判断存储过程是否包含任一目标单词 AND REGEXP_LIKE(object_definition(object_id), N'michael|Kuldeep');
方案2:低版本SQL Server(2016及以下)实现
若不支持内置正则函数,可通过PATINDEX循环匹配统计每个单词的出现次数:
DECLARE @proc_def NVARCHAR(MAX); DECLARE @count_michael INT = 0, @count_kuldeep INT = 0; DECLARE @pos INT; -- 获取目标存储过程的定义 SELECT @proc_def = object_definition(object_id) FROM sys.procedures WHERE name = 'MenuDetailsSelect' AND type = 'P'; -- 统计michael的出现次数 SET @pos = PATINDEX('%michael%', @proc_def); WHILE @pos > 0 BEGIN SET @count_michael += 1; -- 移除已匹配的单词,避免重复统计 SET @proc_def = STUFF(@proc_def, @pos, LEN('michael'), ''); SET @pos = PATINDEX('%michael%', @proc_def); END -- 重新获取存储过程定义,避免影响下一个单词的统计 SELECT @proc_def = object_definition(object_id) FROM sys.procedures WHERE name = 'MenuDetailsSelect' AND type = 'P'; -- 统计Kuldeep的出现次数 SET @pos = PATINDEX('%Kuldeep%', @proc_def); WHILE @pos > 0 BEGIN SET @count_kuldeep += 1; SET @proc_def = STUFF(@proc_def, @pos, LEN('Kuldeep'), ''); SET @pos = PATINDEX('%Kuldeep%', @proc_def); END -- 输出结果 SELECT 'MenuDetailsSelect' AS name, @count_michael AS michael_count, @count_kuldeep AS kuldeep_count, @count_michael + @count_kuldeep AS total_count;
内容的提问来源于stack exchange,提问作者user16491190
相关产品推荐
相关产品推荐

