如何在动态T-SQL存储过程中使用GROUP BY统计模块记录数
动态T-SQL存储过程实现带日期过滤的模块记录统计
首先注意到你提供的表结构中字段名为NameOfModel,但静态统计语句中写的是NameOfModule,这是笔误,下面的代码会统一使用表结构中的NameOfModel(如果实际字段是NameOfModule,你自行替换即可)。
以下是完整的动态存储过程实现,已整合GROUP BY并处理日期参数的动态过滤:
CREATE PROCEDURE dbo.GetModuleRecordCount @datestart datetime2(7) = NULL, @dateend datetime2(7) = NULL AS BEGIN SET NOCOUNT ON; -- 初始化动态SQL变量 DECLARE @sql NVARCHAR(MAX) = N' SELECT NameOfModel AS ModuleName, COUNT(*) AS NumberOfRecords FROM dbo.ReqInfo '; -- 动态拼接日期过滤条件 DECLARE @whereClauses NVARCHAR(MAX) = N''; IF @datestart IS NOT NULL BEGIN SET @whereClauses += N'CreatedDate >= @datestart '; END IF @dateend IS NOT NULL BEGIN IF @whereClauses <> N'' BEGIN SET @whereClauses += N'AND '; END SET @whereClauses += N'CreatedDate <= @dateend '; END -- 如果有过滤条件,添加WHERE子句 IF @whereClauses <> N'' BEGIN SET @sql += N'WHERE ' + @whereClauses; END -- 添加固定的GROUP BY子句 SET @sql += N' GROUP BY NameOfModel; '; -- 使用sp_executesql执行动态SQL,参数化传递避免SQL注入 EXEC sp_executesql @sql, N'@datestart datetime2(7), @dateend datetime2(7)', @datestart = @datestart, @dateend = @dateend; END GO
关键说明:
- GROUP BY整合:GROUP BY是固定的统计逻辑,直接拼接在动态SQL的末尾即可,不需要动态处理(除非你有动态分组的需求,但这里需求是固定按模块分组)。
- 参数安全:使用
sp_executesql而非直接EXEC,并通过参数化方式传递日期参数,彻底避免SQL注入风险。 - 空参数处理:当
@datestart或@dateend为NULL时,不会添加对应的过滤条件,存储过程会统计所有数据的分组结果,和你的静态语句逻辑一致。
调用示例:
-- 统计2023年1月1日到2023年12月31日的模块记录数 EXEC dbo.GetModuleRecordCount @datestart = '2023-01-01', @dateend = '2023-12-31'; -- 统计所有数据的模块记录数(和静态语句效果一致) EXEC dbo.GetModuleRecordCount;
内容的提问来源于stack exchange,提问作者ani H
相关产品推荐
相关产品推荐

