------------------------------------游标的实例---------------------------------------
-------------------------------------------------------------------------------------
--游标的概念
--游标(Cursor)它使用户可逐行访问由SQL Server返回的结果集。使用游标(cursor)的一个主要的原因就是把集合操作转换成单个记录处理方式。用SQL语言从数据库中检索数据后,结果放在内存的一块区域中,且结果往往是一个含有多个记录的集合。游标机制允许用户在SQL server内逐行地访问这些记录,按照用户自己的意愿来显示和处理这些记录。
--游标的优点
--从游标定义可以得到游标的如下优点,这些优点使游标在实际应用中发挥了重要作用:
--1)允许程序对由查询语句select返回的行集合中的每一行执行相同或不同的操作,而不是对整个行集合执行同一个操作。
--2)提供对基于游标位置的表中的行进行删除和更新的能力。
--3)游标实际上作为面向集合的数据库管理系统(RDBMS)和面向行的程序设计之间的桥梁,使这两种处理方式通过游标沟通起来。
-- T-SQL中的游标定义在MSDN中如下:
-- DECLARE cursor_name CURSOR [ LOCAL | GLOBAL ]
-- [ FORWARD_ONLY | SCROLL ]
-- [ STATIC | KEYSET | DYNAMIC | FAST_FORWARD ]
-- [ READ_ONLY | SCROLL_LOCKS | OPTIMISTIC ]
-- [ TYPE_WARNING ]
-- FOR select_statement
-- [ FOR UPDATE [ OF column_name [ ,...n ] ] ]
-- [;]
--
-- LOCAL和GLOBAL二选一
-- LOCAL意味着游标的生存周期只在批处理或函数或存储过程中可见.
-- GLOBAL意味着游标对于特定连接作为上下文,全局内有效
-- FORWARD_ONLY 和 SCROLL 二选一
--FORWARD_ONLY意味着游标只能从数据集开始向数据集结束的方向读取,FETCH NEXT是唯一的选项
--SCROLL支持游标在定义的数据集中向任何方向,或任何位置移动
-- STATIC KEYSET DYNAMIC 和 FAST_FORWARD 四选一
-- 这四个关键字是游标所在数据集所反应的表内数据和游标读取出的数据的关系
-- STATIC意味着,当游标被建立时,将会创建FOR后面的SELECT语句所包含数据集的副本存入tempdb数据库中,任何对于底层表内数据的更改不会影响到游标的内容.
-- DYNAMIC是和STATIC完全相反的选项,当底层数据库更改时,游标的内容也随之得到反映,在下一次fetch中,数据内容会随之改变
-- KEYSET可以理解为介于STATIC和DYNAMIC的折中方案。将游标所在结果集的唯一能确定每一行的主键存入tempdb,当结果集中任何行改变或者删除时,@@FETCH_STATUS会为-2,KEYSET无法探测新加入的数据
-- FAST_FORWARD可以理解成FORWARD_ONLY的优化版本.FORWARD_ONLY执行的是静态计划,而FAST_FORWARD是根据情况进行选择采用动态计划还是静态计划,大多数情况下FAST_FORWARD要比FORWARD_ONLY性能略好.
-- READ_ONLY SCROLL_LOCKS OPTIMISTIC 三选一
-- READ_ONLY意味着声明的游标只能读取数据,游标不能做任何更新操作
-- SCROLL_LOCKS是另一种极端,将读入游标的所有数据进行锁定,防止其他程序进行更改,以确保更新的绝对成功
-- OPTIMISTIC是相对比较好的一个选择,OPTIMISTIC不锁定任何数据,当需要在游标中更新数据时,如果底层表数据更新,则游标内数据更新不成功,如果,底层表数据未更新,则游标内表数据可以更新
--
--游标的操作步骤:
--1.声明游标
--2.打开游标
--3.读取数据
--4.关闭游标
--5.释放游标
declare @name varchar(50)
declare st_cursor scroll cursor for select empName from Tab_Salary --声明游标
open st_cursor --打开游标
--读取数据
--取第一行
fetch first from st_cursor into @name
print @name
--取最后一行
fetch last from st_cursor into @name
print @name
--取下一行
fetch next from st_cursor into @name
print @name
--取上一行
fetch prior from st_cursor into @name
print @name
--取第二行【absolute(n):跳到第n行】
fetch absolute 2 from st_cursor into @name
print @name
--取上一行【relative(n):相对当前位置取第n行,-1当前位置的上一行,1当前位置下一行,如果超出n行,则为当前行数据】
fetch relative -1 from st_cursor into @name
print @name
close st_cursor --关闭游标
deallocate st_cursor --释放游标
------------------------------------实战练习-----------------------------------------
--我们先建两张表
--工资表
create table Tab_Salary
(
id int identity(1,1),
empId varchar(20) primary key,
empName varchar(50),
Salary decimal(18,2)
)
insert into Tab_Salary values('A001','陈飞刚',1000.50),
('B001','杨帆',900.50),
('C001','吴磊',750.80)
go
--额外工资表
create table Tab_Extra_Salary
(
id int identity(1,1),
empId varchar(20),
Extr_Salary decimal(18,2)
)
insert into Tab_Extra_Salary values('A001',200.00),
('B001',100.50),
('C001',600.80),
('B001',800.00)
go
--现在我们做一个简单的练习:用游标打印出额外工资表Extra_Salary的数据
create proc pro_cursor
as
declare @empId varchar(20)
declare @Extr_Salary decimal(18,2)
declare mycursor cursor for select empId,Extr_Salary from Tab_Extra_Salary --声明游标
open mycursor --打开游标
fetch next from mycursor into @empId,@Extr_Salary
while(@@FETCH_STATUS=0) --遍历所有的数据
begin
print '游标成功取出一条数据!'
print @empId
print @Extr_Salary
fetch next from mycursor into @empId,@Extr_Salary --取下一条游标数据
end
close mycursor --关闭游标
deallocate mycursor --删除游标
go
exec pro_cursor
go
--加强练习:将工资表中员工的工资与该员工额外工资表中的额外工资对应的计算总和,然后在工资表中Salary显示出来
--说简单点:Salary=Salary+Extr_Salary
create proc pro_Salary
as
declare @empId varchar(20)
declare @Extr_Salary decimal(18,2)
declare extrSalary_cursor cursor for select empId,Extr_Salary from Tab_Extra_Salary
open extrSalary_cursor
fetch next from extrSalary_cursor into @empId,@Extr_Salary
while(@@FETCH_STATUS=0)
begin
update Tab_Salary set Salary=Salary+@Extr_Salary where empId=@empId
fetch next from extrSalary_cursor into @empId,@Extr_Salary
end
close extrSalary_cursor
deallocate extrSalary_cursor
go
exec pro_Salary
go
--来看看刚刚游标执行的效果有没有加上去
select * from Tab_Salary
go
SQL Server 游标使用
最后编辑于 :
©著作权归作者所有,转载或内容合作请联系作者
- 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
- 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
- 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...