游标是一种能从数据集中每次提取一条记录的机制。游标充当指针的作用。尽管游标能遍历结果中的所有行,但他一次只指向一行。
在直接操作数据库时,包括Transact_SQL 脚本、存储过程和触发器中,经常会遇到需要循环数据的情况,这个时候游标就派上用场了。
游标一般分为 声明 / 打开 / 使用 / 关闭 / 销毁几个步骤
1.游标的声明
这样我就声明了一个名称为 ScrollNo_cursor 的游标,里面的内容是查询出来的 ScrollNo
--开启游标
OPEN ScrollNo_cursor;
--定义一个变量
DECLARE @newScrollNo NVARCHAR(50);
--获取游标内一个内容赋值给变量
FETCH NEXT FROM ScrollNo_cursor
INTO @newScrollNo;
--声明条件,意思是符合条件就执行BEGIN 后面的内容
--@@fetch_status = 0 是判断游标内容存在
WHILE @@fetch_status = 0
BEGIN
UPDATE *** SET ***
--使用完上个内容则使用下一个,一定要记得声明这一个,就是把下一个游标值赋值给变量
--不然程序就一直使用第一个且会陷入死循环造成执行超时
FETCH NEXT FROM ScrollNo_cursor
INTO @newScrollNo;
END
--用完之后记得关闭和删除游标,因为游标是比较占内存的,忘记关闭的话甚至可能造成崩溃
不过据说游标速度比较慢,还有一种循环的写法
声明一个临时表接收查询结果
DECLARE @ScanList AS TABLE
(
ContractNo NVARCHAR(20)
)
--创建索引 加快查询速度,但会影响更新和写入,所以最后要删除这个索引,减小影响
CREATE INDEX RecordIndex ON UDT_PM_ScanRecord(ContractNo)
把插询结果插入临时表
INSERT INTO @ScanList SELECT DISTINCT ContractNo FROM UDT_PM_ScanRecord WHERE createDate
BETWEEN @fromDate AND @toDate
使用循环遍历临时表里面的结果
WHILE EXISTS(SELECT 1 FROM @ScanList)
BEGIN
SELECT TOP 1 @ContractNo=ContractNo FROM @ScanList 拿出临时表里面的第一个
。。。。。编写业务逻辑
DELETE @ScanList WHERE ContractNo=@ContractNo 删除临时表中已经用过的那条记录
END