【MSSql2000】游标

本文介绍了一种使用SQL创建临时表并结合主键表和外键表数据的方法,实现个性化学生分数的整合和展示。
if object_id('tempdb..#StuScore') is null    
create table #StuScore (
	[StuScoreID] [int]IDENTITY (1, 1) NOT NULL ,
	[StuName] [varchar] (50) COLLATE Chinese_PRC_CI_AS NULL ,
	[Details] [varchar] (100) COLLATE Chinese_PRC_CI_AS NULL 
 )
else DELETE FROM #StuScore

declare @stuID varchar(100)--嵌套游标查询条件,主键表的主键
declare @stuName varchar(100)--沿用原表(姓名),主键表字段姓名

declare @scoreName varchar(100)--需要组合的外键表的字段
declare @score varchar(100)--需要组合的外键表的字段
declare @scoreInfo varchar(100)--组合成的字段

declare stuCursor scroll cursor for select UserInfoID,UserName from UserInfo--游标1查询主键表
open stuCursor--打开游标
fetch from stuCursor into @stuID,@stuName--取出游标第一条记录

set @scoreInfo=''--用于循环赋值

	while @@fetch_status=0--取值成功,循环开始
	begin
	declare scoreCursor scroll cursor for select ScoreName,Score from ScoreInfo where UserInfoID=@stuID--游标2条件查询外键表
	open scoreCursor--打开游标
	fetch from scoreCursor into @scoreName,@score--取出游标第一条记录
		while @@fetch_status=0--取值成功,循环开始
		begin
		set @scoreInfo=@scoreInfo+@scoreName+':'+@score+' '--将取出的值循环赋给@scoreInfo
		fetch from scoreCursor into @scoreName,@score--取游标第二条记录--print @scoreInfo
		end--循环结束
	insert into #StuScore(StuName,Details) values(@stuName,@scoreInfo)--第一条记录组合完毕,插入表#StuScore当中
	close scoreCursor--关闭游标2
	deallocate scoreCursor--删除游标引用2	
	set @scoreInfo=''--清空@scoreInfo以去除残留的上一次组合的记录
	fetch from stuCursor into @stuID,@stuName--取出游标第二条记录
	end--循环结束
close stuCursor--关闭游标1
deallocate stuCursor--删除游标引用1
go

select * from #StuScore
select * from UserInfo
select * from ScoreInfo


execute StudentScore



(所影响的行数为 1 行)


(所影响的行数为 1 行)

StuScoreID  StuName                                            Details                                                                                              
----------- -------------------------------------------------- ---------------------------------------------------------------------------------------------------- 
1           李四                                                 语文:90 数学:90 物理:90 
2           张三                                                 语文:80 英语:80 历史:80 数学:80 

(所影响的行数为 2 行)

UserInfoID  UserName                                           
----------- -------------------------------------------------- 
1           李四
2           张三

(所影响的行数为 2 行)

ScoreID     ScoreName                                          Score       UserInfoID  
----------- -------------------------------------------------- ----------- ----------- 
1           语文                                                 90          1
2           数学                                                 90          1
3           语文                                                 80          2
4           英语                                                 80          2
5           历史                                                 80          2
6           数学                                                 80          2
7           物理                                                 90          1

(所影响的行数为 7 行)



在 Microsoft SQL Server (MSSQL) 中,游标是一种数据库对象,用于逐行处理查询结果集。与集合操作不同,游标支持对每一行数据进行单独访问和处理,适用于需要行级操作的场景,例如复杂的业务逻辑或数据逐行更新。尽管游标提供了灵活性,但其性能开销较大,因此在使用时需谨慎并遵循最佳实践。 ### 游标的使用方法 MSSQL游标的使用通常包括以下几个步骤:声明、打开、提取、关闭和释放。 #### 1. 声明游标 使用 `DECLARE CURSOR` 语句定义游标及其关联的 `SELECT` 查询。可以指定游标的类型,如 `STATIC`、`KEYSET`、`DYNAMIC` 或 `FAST_FORWARD`。 ```sql DECLARE EmployeeCursor CURSOR FOR SELECT EmployeeID, Name, Department FROM Employees; ``` #### 2. 打开游标 使用 `OPEN` 语句激活游标,并执行其关联的 `SELECT` 查询。 ```sql OPEN EmployeeCursor; ``` #### 3. 提取数据 使用 `FETCH NEXT FROM` 语句逐行获取数据。 ```sql DECLARE @EmployeeID INT, @Name NVARCHAR(100), @Department NVARCHAR(100); FETCH NEXT FROM EmployeeCursor INTO @EmployeeID, @Name, @Department; WHILE @@FETCH_STATUS = 0 BEGIN PRINT 'Employee ID: ' + CAST(@EmployeeID AS NVARCHAR) + ', Name: ' + @Name + ', Department: ' + @Department; FETCH NEXT FROM EmployeeCursor INTO @EmployeeID, @Name, @Department; END ``` #### 4. 关闭和释放游标 使用 `CLOSE` 和 `DEALLOCATE` 语句释放资源。 ```sql CLOSE EmployeeCursor; DEALLOCATE EmployeeCursor; ``` ### 游标的类型 MSSQL 支持多种类型的游标,每种类型适用于不同的场景: - **STATIC**:创建结果集的静态副本,不反映对基表的更改[^3]。 - **KEYSET**:只反映对现有行的更改,但不反映新插入的行。 - **DYNAMIC**:完全反映对基表的所有更改。 - **FAST_FORWARD**:优化的只进只读游标,性能较好。 ### 最佳实践 1. **避免不必要的使用** 游标通常比基于集合的操作效率低。在可能的情况下,优先使用 `JOIN`、子查询或窗口函数等集合操作。 2. **选择合适的游标类型** 根据业务需求选择适当的游标类型。例如,如果不需要实时反映数据变化,使用 `STATIC` 游标以减少资源消耗。 3. **限制结果集大小** 在声明游标时,尽量通过 `WHERE` 子句限制结果集大小,以减少内存占用和提高性能。 4. **及时关闭和释放游标** 游标会占用数据库资源,应在使用完毕后立即关闭并释放。 5. **考虑替代方案** 对于某些操作,如逐行更新,可以使用 `UPDATE` 语句结合 `FROM` 子句实现,避免使用游标。 6. **监控性能** 使用 SQL Server Profiler 或动态管理视图(DMVs)监控游标的性能影响,确保不会造成系统瓶颈。 ### 示例:使用 `FAST_FORWARD` 游标 ```sql DECLARE @EmployeeID INT, @Name NVARCHAR(100), @Department NVARCHAR(100); DECLARE EmployeeCursor CURSOR FAST_FORWARD FOR SELECT EmployeeID, Name, Department FROM Employees; OPEN EmployeeCursor; FETCH NEXT FROM EmployeeCursor INTO @EmployeeID, @Name, @Department; WHILE @@FETCH_STATUS = 0 BEGIN PRINT 'Processing Employee: ' + @Name; FETCH NEXT FROM EmployeeCursor INTO @EmployeeID, @Name, @Department; END CLOSE EmployeeCursor; DEALLOCATE EmployeeCursor; ``` ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

csdou

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值