SQL Server数据库--游标
游标介绍:
SQLSERVER对数据访问的一种机制,它允许用户对数据结果集进行逐条的访问。
访问的都是单条语句,避免锁表
优点:
游标实际上是一种能从包括多条数据记录的结果集中每次提取一条记录的机制。游标充当指针的作用。尽管游标能遍历结果中的所有行,但他一次只指向一行。
概括来讲,SQL的游标是一种临时的数据库对象,即可以用来存放在数据库表中的数据行副本,也可以指向存储在数据库中的数据行的指针。游标提供了在逐行的基础上操作表中数据的方法。
游标的一个常见用途就是保存查询结果,以便以后使用。游标的结果集是由SELECT语句产生,如果处理过程需要重复使用一个记录集,那么创建一次游标而重复使用若干次,比重复查询数据库要快的多。
大部分程序数据设计语言都能使用游标来检索SQL数据库中的数据,在程序中嵌入游标和在程序中嵌入SQL语句相同。
缺点
因为我们做的数据量大,而且系统上跑的不只我们一个业务。所以,我们都要求尽量避免使用游标,游标使用时会对行加锁,可能会影响其他业务的正常进行。而且,数据量大时其效率也较低效。另外,内存也是其中一个限制。
因为游标其实是相当于把磁盘数据整体放入了内存中,如果游标数据量大则会造成内存不足,内存不足带来的影响大家都知道了。
所以,在数据量小时才使用游标。
游标常用的有三种
第一种:只进游标
第二种:静态游标static
第三种:动态游标dynamic
游标的执行过程
第一步、定义游标
第二步、打开 分为:全局 global 和 本地 local ,全局游标:多个存储过程,触发器
第三步、使用
第四步、关闭
第五步、释放游标
代码先睹为快
sql Product表 代码
USE [DBTase] GO /****** Object: Table [dbo].[Product] Script Date: 2022/3/21 17:24:21 ******/ SET ANSI_NULLS ON GO SET QUOTED_IDENTIFIER ON GO CREATE TABLE [dbo].[Product]( [ID] [int] IDENTITY(1,1) NOT NULL, [TypeID] [int] NULL, [Name] [nvarchar](50) NULL, CONSTRAINT [PK_Product] PRIMARY KEY CLUSTERED ( [ID] ASC )WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY] ) ON [PRIMARY] GO SET IDENTITY_INSERT [dbo].[Product] ON GO INSERT [dbo].[Product] ([ID], [TypeID], [Name]) VALUES (1, 1, N'苹果手机') GO INSERT [dbo].[Product] ([ID], [TypeID], [Name]) VALUES (3, 1, N'三星手机') GO INSERT [dbo].[Product] ([ID], [TypeID], [Name]) VALUES (4, 1, N'华为手机') GO INSERT [dbo].[Product] ([ID], [TypeID], [Name]) VALUES (5, 1, N'小米手机') GO INSERT [dbo].[Product] ([ID], [TypeID], [Name]) VALUES (7, 2, N'苹果电脑') GO INSERT [dbo].[Product] ([ID], [TypeID], [Name]) VALUES (8, 2, N'戴尔电脑') GO INSERT [dbo].[Product] ([ID], [TypeID], [Name]) VALUES (9, 3, N'小米手环') GO INSERT [dbo].[Product] ([ID], [TypeID], [Name]) VALUES (10, 3, N'华为手环') GO SET IDENTITY_INSERT [dbo].[Product] OFF GO ALTER TABLE [dbo].[Product] WITH CHECK ADD CONSTRAINT [FK_product_Type] FOREIGN KEY([TypeID]) REFERENCES [dbo].[Type] ([TypeID]) GO ALTER TABLE [dbo].[Product] CHECK CONSTRAINT [FK_product_Type] GO
ID | TypeID | Name |
1 | 1 | 苹果手机 |
3 | 1 | 三星手机 |
4 | 1 | 华为手机 |
5 | 1 | 小米手机 |
7 | 2 | 苹果电脑 |
8 | 2 | 戴尔电脑 |
9 | 3 | 小米手环 |
10 | 3 | 华为手环 |
游标代码
第一种写法
/*----第一种写法---*/ --定义游标 智能指针 declare _product_cursor cursor for select ID, TypeID, Name from Product; --给游标赋值,此时游标属于内存中的一张表 --定义一个和 Product字段一致的游标 declare @productCursor cursor,@ID int,@TypeID int,@Name nvarchar(50); set @productCursor=_product_cursor;--赋值 open @productCursor --打开游标 --向下 next 向上:prior 第一个:first 最后一个 last fetch next from @productCursor into @ID,@TypeID,@Name--游标前进 into 赋值 while @@FETCH_STATUS=0 --判断是否执行成功 begin print cast(@ID as varchar)+','+cast(@TypeID as varchar)+','+cast(@Name as varchar) fetch next from @productCursor into @ID,@TypeID,@Name--游标前进 into 赋值 end --关闭游标 close _product_cursor --释放游标 deallocate _product_cursor
第二种写法
/*----第二种写法---*/ --定义游标 智能指针 declare _product_cursor cursor for select ID, TypeID, Name from Product; --给游标赋值,此时游标属于内存中的一张表 --定义一个和 Product字段一致的变量 declare @ID int,@TypeID int,@Name nvarchar(50); open _product_cursor --打开游标 --向下 next 向上:prior 第一个:first 最后一个 last fetch next from _product_cursor into @ID,@TypeID,@Name--游标前进 into 赋值 while @@FETCH_STATUS=0 --判断是否执行成功 begin print cast(@ID as varchar)+','+cast(@TypeID as varchar)+','+cast(@Name as varchar) fetch next from _product_cursor into @ID,@TypeID,@Name--游标前进 into 赋值 end --关闭游标 close _product_cursor --释放游标 deallocate _product_cursor
第一种:只进游标
第一步:定义游标
declare product_cursor cursor --定义游标 智能指针 for select ProductNo,ProductName,Price from Product;
第二步:打开游标
global:全局 local:本地 (默认)
全局游标:多个存储过程,触发器
open product_cursor
第三步:使用游标
定义其它用于存放信息的变量
@varCursor用于存放单行数据
declare @varCursor cursor,@pno int,@pname varchar(50),@price money set @varCursor=product_cursor--赋值 --向下 next 向上:prior 第一个:first 最后一个 last --这个例子讲的是“只进游标”所以只能用next fetch next from @varCursor into @pno,@pname,@price--游标前进 into 赋值 while @@FETCH_STATUS=0 --判断是否执行成功 begin print cast(@pno as varchar)+','+@pname+','+cast(@price as varchar) fetch next from @varCursor into @pno,@pname,@price--游标前进 into 赋值 end
第四步:关闭游标
close product_cursor --关闭游标
第五步:释放游标
deallocate product_cursor --释放游标
第二种:静态游标static
第一步:定义游标
declare product_cursor cursor static --定义静态游标 for select ProductNo,ProductName,Price from Product;
第二步:打开游标
global:全局 local:本地
全局游标:多个存储过程,触发器
open product_cursor
第三步:使用游标
定义其它用于存放信息的变量
@varCursor用于存放单行数据
absolute:绝对定位 (从第几行读取)
relative:相对定位 (从当前行数,向下或向上第几行读取)
下面例子演示的是relative相对定位
declare @varCursor cursor,@pno int,@pname varchar(50),@price money set @varCursor=product_cursor--赋值 --向下 next 向上:prior 第一个:first 最后一个 last --absolute:绝对定位 相对定位:relative fetch relative 2 from @varCursor into @pno,@pname,@price--游标前进 into 赋值 print cast(@pno as varchar)+','+@pname+','+cast(@price as varchar) while @@FETCH_STATUS=0 --判断是否执行成功 begin print cast(@pno as varchar)+','+@pname+','+cast(@price as varchar) fetch next from @varCursor into @pno,@pname,@price--游标前进 into 赋值 end
第四步:关闭游标
close product_cursor
第五步:释放游标
deallocate product_cursor
第三种:动态游标dynamic
第一步:定义游标
declare product_cursor cursor dynamic --定义静态游标 for select ProductNo,ProductName,Price from Product; --动态游标保存的是可变结果集
第二步:打开游标
global:全局
local:本地
全局游标:多个存储过程,触发器
open product_cursor
第三步:使用游标
定义其它用于存放信息的变量
@varCursor用于存放单行数据
declare @varCursor cursor,@pno int,@pname varchar(50),@price money set @varCursor=product_cursor--赋值 --向下 next 向上:prior 第一个:first 最后一个 last --absolute:绝对定位 相对定位:relative fetch next from @varCursor into @pno,@pname,@price--游标前进 into 赋值 print cast(@pno as varchar)+','+@pname+','+cast(@price as varchar) while @@FETCH_STATUS=0 --判断是否执行成功 begin print cast(@pno as varchar)+','+@pname+','+cast(@price as varchar) fetch next from @varCursor into @pno,@pname,@price--游标前进 into 赋值 end
第四步:关闭游标
close product_cursor
第五步:释放游标
deallocate product_cursor