在数据库开发过程中,我们经常会碰到要遍历数据表的情形,一提到遍历表,我们第一印象可能就想到使用游标,使用游标虽然直观易懂,但是它不符合面向集合操作的原则,而且性能也比面向集合低。当然,从面向集合操作的角度出发,也有两种方法可以进行遍历表的操作,总结起来,遍历表有下面几种方法。

  1. 使用游标
  2. 使用表变量
  3. 使用临时表

我的需求是:针对HR.Employees表,新增一列fullname,并取值firstname+lastname。

  1. -- 需求是,新增一列fullname,取值firstname+lastname
  2. ALTER TABLE HR.Employees ADD fullname NVARCHAR(30) NULL;
  3. GO

原始效果如下图。

这个需求本来可以一条sql语句搞定,如下代码所示。但是为了演示表的遍历,我还是使用了这三种方式来实现一下。

  1. USE TSQLFundamentals2008;
  2. GO
  3.  
  4. UPDATE HR.Employees SET fullname= firstname+' '+lastname;

使用游标

  使用游标的代码比较繁琐,概括起来主要有以下几个步骤,声明游标,打开游标,使用游标,关闭游标和释放游标。示例代码如下。

  1. -- 方法1:游标
  2. -- 声明变量
  3. DECLARE
  4. @empid AS INT,
  5. @firstname AS NVARCHAR(10),
  6. @lastname AS NVARCHAR(20);
  7.  
  8. -- 声明游标
  9. DECLARE C_Employees CURSOR FAST_FORWARD FOR
  10. SELECT empid,firstname,lastname
  11. FROM HR.Employees
  12. ORDER BY empid;
  13.  
  14. OPEN C_Employees;
  15.  
  16. -- 取第一条记录
  17. FETCH NEXT FROM C_Employees INTO @empid,@firstname,@lastname;
  18.  
  19. WHILE @@FETCH_STATUS=0
  20. BEGIN
  21. -- 操作
  22. UPDATE HR.Employees SET fullname= @firstname+' '+@lastname WHERE empid=@empid;
  23.  
  24. -- 取下一条记录
  25. FETCH NEXT FROM C_Employees INTO @empid,@firstname,@lastname;
  26. END
  27.  
  28. -- 关闭游标
  29. CLOSE C_Employees;
  30.  
  31. -- 释放游标
  32. DEALLOCATE C_Employees;

运行脚本,效果如下图。

可以看到,已经达到我们想要的效果了。

使用表变量

  因为使用游标存在性能和违背面向集合思想的问题,所以我们有必要用面向集合的思想去找到一种更好的解决方案,下面这种方法是使用表变量的方式实现的,代码如下。

  1. 1 -- 方法2:使用表变量
  2. 2 -- 声明表变量
  3. 3 DECLARE @temp TABLE
  4. 4 (
  5. 5 empid INT,
  6. 6 firstname NVARCHAR(10),
  7. 7 lastname NVARCHAR(20)
  8. 8 );
  9. 9
  10. 10 -- 将源表中的数据插入到表变量中
  11. 11 INSERT INTO @temp(empid, firstname, lastname )
  12. 12 SELECT empid,firstname,lastname FROM HR.Employees
  13. 13 ORDER BY empid;
  14. 14
  15. 15 -- 声明变量
  16. 16 DECLARE
  17. 17 @empid AS INT,
  18. 18 @firstname AS NVARCHAR(10),
  19. 19 @lastname AS NVARCHAR(20);
  20. 20
  21. 21 WHILE EXISTS(SELECT empid FROM @temp)
  22. 22 BEGIN
  23. 23 -- 也可以使用top 1
  24. 24 SET ROWCOUNT 1
  25. 25 SELECT @empid= empid, @firstname= firstname,@lastname= lastname FROM @temp;
  26. 26 UPDATE HR.Employees SET fullname= @firstname+' '+@lastname WHERE empid=@empid;
  27. 27 SET ROWCOUNT 0
  28. 28
  29. 29 DELETE FROM @temp WHERE empid=@empid;
  30. 30 END

使用临时表

  临时表也可以实现表变量的功能,所以我们也可以使用临时表来实现这个需求,代码如下。

  1. 1 -- 方法3:使用临时表
  2. 2 -- 创建临时表
  3. 3 IF OBJECT_ID('tempdb.dbo.#tempemployees','U') IS NOT NULL DROP TABLE dbo.#tempemployees;
  4. 4 GO
  5. 5
  6. 6 SELECT empid,firstname,lastname
  7. 7 INTO dbo.#tempemployees
  8. 8 FROM HR.Employees
  9. 9 ORDER BY empid;
  10. 10
  11. 11 --SELECT * FROM dbo.#tempemployees;
  12. 12
  13. 13 -- 声明变量
  14. 14 DECLARE
  15. 15 @empid AS INT,
  16. 16 @firstname AS NVARCHAR(10),
  17. 17 @lastname AS NVARCHAR(20);
  18. 18
  19. 19 WHILE EXISTS(SELECT empid FROM dbo.#tempemployees)
  20. 20 BEGIN
  21. 21 -- 也可以使用top 1
  22. 22 SET ROWCOUNT 1
  23. 23 SELECT @empid= empid, @firstname= firstname,@lastname= lastname FROM dbo.#tempemployees;
  24. 24 UPDATE HR.Employees SET fullname= @firstname+' '+@lastname WHERE empid=@empid;
  25. 25 SET ROWCOUNT 0
  26. 26
  27. 27 DELETE FROM dbo.#tempemployees WHERE empid=@empid;
  28. 28 END

当然,实现的效果都是一样的。

转载:

https://www.cnblogs.com/mcgrady/p/4182486.html

sqlserver 表循环-游标、表变量、临时表的更多相关文章

  1. SQL Server循环——游标、表变量、临时表

    游标 在游标逐行处理过程中,当需要处理的记录数较大,而且游标处理位于数据库事务内时,速度非常慢. -- 声明变量 DECLARE @Id AS Int -- 声明游标 DECLARE C_Id CUR ...

  2. sql循环-游标、临时表、表变量

    游标 在游标逐行处理过程中,当需要处理的记录数较大,而且游标处理位于数据库事务内时,速度非常慢. -- 声明变量 DECLARE @Id AS Int -- 声明游标 DECLARE C_Id CUR ...

  3. 使用whIle循环语句和变量打印九九乘法表

    -设置i变量declare @i int --设置j变量declare @j int --设置乘法表变量declare @chengfabiao varchar(1000)--给i,j,@chengf ...

  4. SQLSERVER和ORACLE系统表获取表名 列名以及列的注释

    在工作中从数据库取的数据要导出来,但是发现导出的EXCEL中列名都是字段名(英文),为此搜集资料怎么把字段名变为中文名称,而发现ORACLE和SQLSERVER(用的SQLSERVER2008R2)又 ...

  5. 获取SQLSERVER所有库 所有表 所有列 所有字段信息

    最近想起来做一个项目代码生成器,直接生成底层代码.. 这免不了要先行读取数据库已有的信息.. 废话不多说..开整.. SELECT NAME FROM MASTER..SYSDATABASES --读 ...

  6. SQL-Server数据库学习笔记-表

    1. 表及其属性 表(Table):也称实体,是存储同类型数据的集合. 列(Field):也称字段.域或属性,它构成表的架构,具体表示为一条信息中的一个属性. 行(Row):也称元组(Tuple),存 ...

  7. oracle 删除用户,表空间;循环删除表

    select * from dba_tablespaces 说明:查看所有表空间 ----------------------------------------------------------- ...

  8. SqlServer查询数据库所有表

    //SqlServer查询数据库所有表SELECT * FROM SYSOBJECTS WHERE TYPE='U' and name like '%dict%'

  9. 通过修改注册表设置windows环境变量

    开发环境搭建每次都要设置很多环境变量, 一般是通过  [菜单]->[计算机]->[属性]->[高级设置]->[环境变量]进行设置,重装系统后,每次都要设置很多环境变量,很麻烦. ...

随机推荐

  1. 《Java编程思想第四版》第 16 章 设计范式-提到观察者模式

    在由Gamma,Helm 和 Johnson 编著的<Design Patterns>一书中被定义成一个“里程碑”.那本书列出了解决这个问题的 23 种不同的方法 16.1.2 范式分类 ...

  2. 阿里的fastJson.jar jsonArray 和 list 互转

    阿里的fastJson.jar: //list转换为json List<CustPhone> list = new ArrayList<CustPhone>(); String ...

  3. 函数的if--while流程控制

    一.流程控制---if 1.if条件判断 age=18 hight=1.70 sex="female" is_beautiful=True if sex=="female ...

  4. shell脚本的小记

    作者:邓聪聪 mysql的脚本执行 #!/bin/sh HOST="127.0.0.1" PORT=" UESRNAME="root" PASSWOR ...

  5. EF的三种数据加载方式

    EF的关联实体加载有三种方式:Lazy Loading,Eager Loading,Explicit Loading,其中Lazy Loading和Explicit Loading都是延迟加载. (一 ...

  6. Python-Django 模型层-多表查询-2

    -related_name:基于双下划线的跨表查询,修改反向查询的字段 -related_query_name:基于对象的跨表查询,修改反向查询字段 publish = ForeignKey(Blog ...

  7. 做GUI的随笔

    用的SDL库 官方网站是:https://littlevgl.com/   改网站需要FQ 字库制作网站: https://debugdump.com/t_771.html

  8. django 实战篇之路由层

    路由层 如何给网页添加首页及尾页 urlpatterns = [ url(r'^admin/', admin.site.urls), url(r'test',views.test), url(r'te ...

  9. select2 下拉搜索控件

    1.添加相应的script链接 jquery: <script type="text/javascript" src="http://cdn.bootcss.com ...

  10. [转] 扩展微信小程序框架功能

    通过第三方 JavaScript 库,扩展微信小程序框架功能. 扩展微信小程序框架功能(1)——Promise ES6 对 Promise 有了原生的支持,但微信开发者工具更新版本(0.11.1122 ...