1、题目
要求编写一个存储过程 spGetTest 统计 T_Test 表的数据,执行输出结果如下图:
2、数据
if not object_id('T_Test') is null --判断表是否存在
drop table T_Test --删除表
go
--创建用户金额发生表
create table T_Test(
fUser_Name nvarchar(40), --用户名称
fUser_Dep nvarchar(40), --用户部门
fMoney numeric(24,6), --用户发生金额
fDate datetime --金额发生时间
)
go
--插入测试数据
insert T_Test(fUser_Name,fUser_Dep,fMoney,fDate)
values('小王','营业部',120.3,'2023/06/21 11:00:00')
insert T_Test(fUser_Name,fUser_Dep,fMoney,fDate)
values('小王','营业部',450,'2023/06/21 12:00:00')
insert T_Test(fUser_Name,fUser_Dep,fMoney,fDate)
values('小王','营业部',100,'2023/06/21 14:00:00')
insert T_Test(fUser_Name,fUser_Dep,fMoney,fDate)
values('小李','营业部',110.34,'2023/06/21 10:00:00')
insert T_Test(fUser_Name,fUser_Dep,fMoney,fDate)
values('小李','营业部',120,'2023/06/21 11:00:00')
go
insert T_Test(fUser_Name,fUser_Dep,fMoney,fDate)
values('老刘','生产部',300,'2023/06/21 19:00:00')
insert T_Test(fUser_Name,fUser_Dep,fMoney,fDate)
values('老刘','生产部',150,'2023/06/21 14:00:00')
insert T_Test(fUser_Name,fUser_Dep,fMoney,fDate)
values('郭总','生产部',220,'2023/06/21 11:00:00')
insert T_Test(fUser_Name,fUser_Dep,fMoney,fDate)
values('郭总','生产部',340,'2023/06/21 18:00:00')
insert T_Test(fUser_Name,fUser_Dep,fMoney,fDate)
values('郭总','生产部',60,'2023/06/21 16:00:00')
insert T_Test(fUser_Name,fUser_Dep,fMoney,fDate)
values('郭总','生产部',508,'2023/06/21 13:00:00')
go
insert T_Test(fUser_Name,fUser_Dep,fMoney,fDate)
values('孙总','储运部',400.06,'2023/06/21 14:00:00')
insert T_Test(fUser_Name,fUser_Dep,fMoney,fDate)
values('孙总','储运部',220,'2023/06/21 13:00:00')
insert T_Test(fUser_Name,fUser_Dep,fMoney,fDate)
values('孙总','储运部',520,'2023/06/21 15:00:00')
insert T_Test(fUser_Name,fUser_Dep,fMoney,fDate)
values('小黄','储运部',720,'2023/06/21 16:00:00')
insert T_Test(fUser_Name,fUser_Dep,fMoney,fDate)
values('小黄','储运部',150,'2023/06/21 18:00:00')
insert T_Test(fUser_Name,fUser_Dep,fMoney,fDate)
values('大彭','储运部',190.2,'2023/06/21 12:00:00')
insert T_Test(fUser_Name,fUser_Dep,fMoney,fDate)
values('大彭','储运部',170,'2023/06/21 16:00:00')
insert T_Test(fUser_Name,fUser_Dep,fMoney,fDate)
values('大彭','储运部',180,'2023/06/21 18:00:00')
insert T_Test(fUser_Name,fUser_Dep,fMoney,fDate)
values('大彭','储运部',409,'2023/06/21 12:00:00')
insert T_Test(fUser_Name,fUser_Dep,fMoney,fDate)
values('二胖','储运部',360,'2023/06/21 17:00:00')
3、实现
IF EXISTS (SELECT * FROM sys.objects WHERE name='proc_ybTest')
DROP PROCEDURE proc_ybTest
GO
CREATE PROCEDURE proc_ybTest
AS
BEGIN
DECLARE @depname NVARCHAR(20);
DECLARE @results TABLE (部门 NVARCHAR(20), fUser_Name NVARCHAR(50), 金额 DECIMAL(18, 2), 最近消费时间 DATETIME);
DECLARE dep_name CURSOR FOR SELECT fUser_Dep FROM T_Test GROUP BY fUser_Dep;
OPEN dep_name;
FETCH NEXT FROM dep_name INTO @depname;
WHILE @@FETCH_STATUS = 0
BEGIN
INSERT INTO @results
SELECT
CASE WHEN fUser_Dep=@depname THEN '' END AS 部门,
fUser_Name, SUM(fMoney) AS 金额, MAX(fDate) AS 最近消费时间
FROM T_Test
WHERE fUser_Dep = @depname
GROUP BY fUser_Dep, fUser_Name
UNION ALL
SELECT @depname+'_合计', '', SUM(fMoney), null
FROM T_Test
WHERE fUser_Dep = @depname;
FETCH NEXT FROM dep_name INTO @depname;
END;
CLOSE dep_name;
DEALLOCATE dep_name;
SELECT CASE
WHEN 部门 NOT LIKE '%合计%' THEN ''
ELSE 部门
END AS 部门,
fUser_Name,金额,最近消费时间 FROM @results;
END
exec proc_ybTest
执行存储过程结果如下:
4、解释
4.1AI文字解释
以下是对存储过程进行逐行解释:
-
IF EXISTS (SELECT * FROM sys.objects WHERE name='proc_ybTest')
: 这行代码用于检查是否存在名为proc_ybTest
的存储过程。 -
DROP PROCEDURE proc_ybTest
: 如果存在名为proc_ybTest
的存储过程,则使用DROP PROCEDURE
语句将其删除。 -
GO
:GO
是一个批处理分隔符,它将上述两行代码分隔为两个独立的批处理。 -
CREATE PROCEDURE proc_ybTest
: 创建名为proc_ybTest
的存储过程。 -
AS
:AS
关键字指示存储过程的主体开始。 -
DECLARE @depname NVARCHAR(20);
: 声明一个名为@depname
的变量,用于存储部门名称。 -
DECLARE @results TABLE (部门 NVARCHAR(20), fUser_Name NVARCHAR(50), 金额 DECIMAL(18, 2), 最近消费时间 DATETIME);
: 声明一个名为@results
的表变量,用于存储结果集。 -
DECLARE dep_name CURSOR FOR SELECT fUser_Dep FROM T_Test GROUP BY fUser_Dep;
: 声明名为dep_name
的游标,用于循环遍历部门名称。 -
OPEN dep_name;
: 打开游标,准备开始遍历。 -
FETCH NEXT FROM dep_name INTO @depname;
: 从游标中获取第一条部门名称,并将其存储在@depname
变量中。 -
WHILE @@FETCH_STATUS = 0
: 进入一个循环,只要游标还有更多的数据可获取,就继续循环。 -
BEGIN
: 循环体的开始。 -
INSERT INTO @results
: 将以下查询结果插入到@results
表变量中。- 部门行:根据当前部门名称(
@depname
)查询相应的部门数据,包括部门、用户名、金额和最近消费时间。 - 合计行:根据当前部门名称(
@depname
)查询相应的金额合计,并将部门名称拼接上 "_合计" 后作为部门。
- 部门行:根据当前部门名称(
-
FETCH NEXT FROM dep_name INTO @depname;
: 从游标中获取下一条部门名称,并将其存储在@depname
变量中。 -
END
: 循环体的结束。 -
CLOSE dep_name;
: 关闭游标。 -
DEALLOCATE dep_name;
: 释放游标的资源。 -
SELECT CASE WHEN 部门 NOT LIKE '%合计%' THEN '' ELSE 部门 END AS 部门, fUser_Name, 金额, 最近消费时间 FROM @results;
: 从@results
表变量中选择部门、用户名、金额和最近消费时间,并使用 CASE 语句处理部门名称,使合计行的部门名称为空字符串。
标签:00,Name,Dep,游标,server,fMoney,fUser,sql,Test From: https://www.cnblogs.com/Yytan-BK/p/17556288.html