【数据库】Sql Server 2022通过临时表和游标遍历方式逻辑处理获取目标数据

2023年,第39周。给自己一个目标,然后坚持总会有收货,不信你试试!
今天有个小伙伴咨询一个Sql Server处理数据的问题,刚好重温下SqlServer临时表和游标的知识点

目录

  • 一、需求点描述
  • 二、临时表
    • 2.1、局部临时表(Local Temporary Table)
    • 2.2、全局临时表(Global Temporary Table)
  • 三、游标
    • 3.1、声明游标
    • 3.2、打开游标
    • 3.3、获取数据
    • 3.4、处理数据
    • 3.5、关闭和释放游标
  • 四、解决方案

在这里插入图片描述

一、需求点描述

有如下数据集,有9条记录,如果001前后一条记录都不是001,那么就取001前面一条记录以及本身001这条记录、
如果001下一条记录还是001,则取001最后一条记录以及001刚开始的前一条记录

工作中心序号备注
10011
10022取这条记录
0013取这条记录
10044
10085取这条记录
0016连续出现的首条前一条记录
0017
0018取这条记录
10099

1)查询数据集在这里插入图片描述

2)目标数据集在这里插入图片描述

二、临时表

在 SQL Server 中,临时表是一种用于存储临时数据的特殊表。
临时表可以在查询执行期间被创建,并且只在当前会话或连接有效。
它们对于需要存储临时数据的计算和操作非常有用。

SQL Server 提供了两种类型的临时表:局部临时表(Local Temporary Table)和全局临时表(Global Temporary Table)。

2.1、局部临时表(Local Temporary Table)

局部临时表是以 # 开头的表名,只在创建它的会话中可见。
当创建它的会话结束时,该表会自动删除。其他会话无法访问这个表。

  • 示例创建局部临时表:
CREATE TABLE #TempTable (ID INT,Name VARCHAR(50)
);

2.2、全局临时表(Global Temporary Table)

全局临时表是以 ## 开头的表名,可以在创建它的服务器实例上的任何会话中可见。
当所有引用该表的会话结束时,该表会自动删除。

  • 示例创建全局临时表:
CREATE TABLE ##TempTable (ID INT,Name VARCHAR(50)
);

使用临时表时,可以像操作任何其他表一样进行数据插入、更新、删除和查询。

值得注意的是,临时表的结构(包括列定义和约束)与永久表类似,可以创建索引、触发器等对象。
然而,当会话结束后,临时表和与之相关的对象都会被自动清理和删除。

临时表对于临时性数据存储和处理非常有用,例如在复杂的查询和存储过程中暂存中间结果或存储需要跨多个查询或操作之间共享的临时数据。

三、游标

在 SQL Server 中,游标(Cursor)是一种用于遍历结果集的数据库对象。
它提供了一种逐行处理查询结果的机制,可以在需要逐行操作数据的情况下使用。

  • 以下是使用游标的一般步骤:

3.1、声明游标

使用 DECLARE CURSOR 语句声明游标,并指定游标的名称和要遍历的查询。

DECLARE CursorName CURSOR FORSELECT Column1, Column2FROM TableName;

3.2、打开游标

使用 OPEN 语句打开游标,准备开始遍历结果集。

OPEN CursorName;

3.3、获取数据

使用 FETCH NEXT 语句获取当前游标位置的一行数据,并将其存储到变量中。可以使用 INTO 子句将数据存储到多个变量中。

FETCH NEXT FROM CursorName INTO @Variable1, @Variable2;

3.4、处理数据

在循环中对获取的行数据进行处理。这可以是对数据进行计算、更新、删除等操作,或者仅仅是输出数据。

WHILE @@FETCH_STATUS = 0
BEGIN-- 处理数据-- 例如执行一些操作或输出数据FETCH NEXT FROM CursorName INTO @Variable1, @Variable2;
END;

3.5、关闭和释放游标

使用 CLOSE 关闭游标,将游标的状态置为不可使用,但不删除游标。最后使用 DEALLOCATE 释放游标,并从内存中删除。

CLOSE CursorName;
DEALLOCATE CursorName;

注意事项:

  • 使用游标时要考虑性能和资源占用,因为游标可能导致性能下降,并占用大量内存。
  • 在处理完成后,务必关闭和释放游标,以释放资源。
  • 可以使用 @@FETCH_STATUS 系统变量来判断是否还有更多行可供遍历。

游标的使用需要谨慎考虑,只在必要的情况下使用,尽量使用集合操作来替代游标,以提高性能。

四、解决方案

根据上面了解到的临时表和游标,结合需求,可以做如下逻辑操作,得到目标查询结果

  • 代码如下
-- 创建局部临时表
if object_id('tempdb..#myTempTable') is not null begindrop table #myTempTable
end
/*else begincreate table #myTempTable(工作中心 varchar(50),序号 int)
end*/-- 临时表不存在情况下
select * into #myTempTable from(select '1001' 工作中心,1 序号 union allselect '1002' 工作中心,2 序号 union allselect '001' 工作中心,3 序号 union allselect '1004' 工作中心,4 序号 union allselect '1008' 工作中心,5 序号 union allselect '001' 工作中心,6 序号 union allselect '001' 工作中心,7 序号 union allselect '001' 工作中心,8 序号 union allselect '1009' 工作中心,9 序号
) a-- select * from #myTempTable-- 定义变狼
declare @工作中心 varchar(50)
declare @序号 int
declare @前一个工作中心 varchar(50)
declare @前一个序号 int
set @前一个工作中心='#'-- 定义游标
declare cursorName cursor for
select 工作中心,序号 from #myTempTable-- 打开游标
open cursorName-- 遍历游标
fetch next from cursorName into @工作中心,@序号;
while @@fetch_status=0 begin-- print(@工作中心)if @前一个工作中心='#' beginset @前一个工作中心=@工作中心set @前一个序号=@序号endelse beginif @工作中心='001' beginif @前一个工作中心!='001' begin-- 输出001上的一条记录print(@前一个工作中心+','+convert(varchar(50),@前一个序号))endendelse beginif @前一个工作中心!=@工作中心 and @前一个工作中心='001' begin-- 输出001最后一条print(@前一个工作中心+','+convert(varchar(50),@前一个序号))endendset @前一个工作中心=@工作中心set @前一个序号=@序号end-- 遍历下一条,一定要加上这句,否则会一直循环fetch next from cursorName into @工作中心,@序号;
end-- 关闭和销毁游标
close cursorName
deallocate cursorName
  • 效果如下在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/115240.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

第8章 MySQL的数据目录

8.1 数据库和文件系统的关系 像 InnoDB 、 MyISAM 这样的存储引擎都是把表存储在磁盘上的,而操作系统用来管理磁盘的又被称为 文件系统 ,所以用专业一点的话来表述就是:像 InnoDB 、 MyISAM 这样的存储引擎都是把表存储在文件系统上的。当我…

Python 计算三角形面积

"""计算三角形面积介绍:已知三角形边长分别为x、y、z,可以计算三角形半周长q,然后根据海伦公式计算三角形面积S三角形半周长:q (x y z) / 2三角形面积:S (q * (q-x) * (q-y) * (q-z)) ** 0.5知识点…

Mac 上安装yt-dlp 和下载视频的操作

安装 打开终端,在终端输入 cd python的路径,然后输入pip3 install yt-dlp,如下图; 出现 如Successfully installed yt-dlp-2023.7.6 的时候,说明下载成功 下载 下载命令: yt-dlp --list-formats https…

数据变换:数据挖掘的准备工作之一

⭐️⭐️⭐️⭐️⭐️欢迎来到我的博客⭐️⭐️⭐️⭐️⭐️ 🐴作者:秋无之地 🐴简介:CSDN爬虫、后端、大数据领域创作者。目前从事python爬虫、后端和大数据等相关工作,主要擅长领域有:爬虫、后端、大数据…

提高接口自动化测试效率:使用 JMESPath 实现断言和数据提取!

前言 做接口自动化,断言是比不可少的。如何快速巧妙的提取断言数据就成了关键,当然也可以提高用例的编写效率。笔者在工作中接触到了JMESPath,那到底该如何使用呢?带着疑惑一起往下看。 JMESPath是啥? JMESPath 是一…

LeetCode01

LeetCode01 两数之和 给定一个整数数组 nums 和一个整数目标值 target,请你在该数组中找出 和 为目标值 target 的那两个整数,并返回它们的数组下标。 你可以假设每种输入只会对应一个答案。但是,数组中同一个元素在答案里不能重复出现。 你…

LabVIEW在运行时调整表控件列宽

LabVIEW在运行时调整表控件列宽 如何在LabIEW中运行时调整表控件的列宽大小? 在VI运行时,有两种不同的方法可以更改表中列的宽度。首先,可以使用鼠标手动更改它们;其次,可以从框图中以编程方式更改它们。 手动更改列宽 只有在…

Rsync学习笔记2

Rsync: 增量操作: 1) server01服务文件变动。 [rootserver03 tp5shop]# rsync -av /usr/local/nginx/html/tp5shop root192.168.17.109:/usr/local/nginx/html/ sending incremental file listsent 88,134 bytes received 496 bytes 177,…

GDB的TUI模式(文本界面)

2023年9月22日,周五晚上 今晚在看GDB的官方文档时,发现GDB居然有文本界面模式 TUI (Debugging with GDB) (sourceware.org) GDB开启TUI的条件 GDB的文本界面的开启条件是:操作系统有适当版本的curses库 The TUI mode is supported only on…

【Stm32】【Lin通信协议】Lin通信点亮灯实验

Lin通信点亮灯实验 通过STM32的串口发送数据,然后通过串口转换模块将数据转换成LIN(Local Interconnect Network)协议,最终控制点亮灯。需要工程和入门资料的可以私信我,看到了马上回。 入门书本推荐: 一…

Quartz 建表语句SQL文件

SQL文件在jar里面,github下载 https://github.com/quartz-scheduler/quartz/releases/tag/v2.3.2 解压,sql文件路径:quartz-core\src\main\resources\org\quartz\impl\jdbcjobstore tables_mysql_innodb.sql # # In your Quartz propertie…

Python150题day09

③多条件分支 使用input函数接收用户的输入数据,如果用户输入python,则输出90,如果用户输入java.输出95,如果用户输入php,输出85,其他输入,程序输出0 解答: if...elif...else val…