在数据库开发过程中,我们经常会碰到要遍历数据表的情形,⼀提到遍历表,我们第⼀印象可能就想到使⽤游标,使⽤游标虽然直观易懂,但是它不符合⾯向集合操作的原则,⽽且性能也⽐⾯向集合低。当然,从⾯向集合操作的⾓度出发,也有两种⽅法可以进⾏遍历表的操作,总结起来,遍历表有下⾯⼏种⽅法。1. 使⽤游标2. 使⽤表变量3. 使⽤临时表
我的需求是:针对HR.Employees表,新增⼀列fullname,并取值firstname+lastname。
-- 需求是,新增⼀列fullname,取值firstname+lastname
ALTER TABLE HR.Employees ADD fullname NVARCHAR(30) NULL;GO
原始效果如下图。
这个需求本来可以⼀条sql语句搞定,如下代码所⽰。但是为了演⽰表的遍历,我还是使⽤了这三种⽅式来实现⼀下。
USE TSQLFundamentals2008;GO
UPDATE HR.Employees SET fullname= firstname+' '+lastname;
使⽤游标
使⽤游标的代码⽐较繁琐,概括起来主要有以下⼏个步骤,声明游标,打开游标,使⽤游标,关闭游标和释放游标。⽰例代码如下。
-- ⽅法1:游标-- 声明变量DECLARE
@empid AS INT,
@firstname AS NVARCHAR(10), @lastname AS NVARCHAR(20);
-- 声明游标
DECLARE C_Employees CURSOR FAST_FORWARD FOR SELECT empid,firstname,lastname FROM HR.Employees ORDER BY empid;
OPEN C_Employees;
-- 取第⼀条记录
FETCH NEXT FROM C_Employees INTO @empid,@firstname,@lastname;
WHILE @@FETCH_STATUS=0BEGIN -- 操作
UPDATE HR.Employees SET fullname= @firstname+' '+@lastname WHERE empid=@empid;
-- 取下⼀条记录
FETCH NEXT FROM C_Employees INTO @empid,@firstname,@lastname;END
-- 关闭游标
CLOSE C_Employees;-- 释放游标
DEALLOCATE C_Employees;
运⾏脚本,效果如下图。
可以看到,已经达到我们想要的效果了。
使⽤表变量
因为使⽤游标存在性能和违背⾯向集合思想的问题,所以我们有必要⽤⾯向集合的思想去找到⼀种更好的解决⽅案,下⾯这种⽅法是使⽤表变量的⽅式实现的,代码如下。
1 -- ⽅法2:使⽤表变量 2 -- 声明表变量
3 DECLARE @temp TABLE 4 (
5 empid INT,
6 firstname NVARCHAR(10), 7 lastname NVARCHAR(20) 8 ); 9
10 -- 将源表中的数据插⼊到表变量中
11 INSERT INTO @temp(empid, firstname, lastname )
12 SELECT empid,firstname,lastname FROM HR.Employees13 ORDER BY empid;14
15 -- 声明变量16 DECLARE
17 @empid AS INT,
18 @firstname AS NVARCHAR(10),19 @lastname AS NVARCHAR(20);20
21 WHILE EXISTS(SELECT empid FROM @temp)22 BEGIN
23 -- 也可以使⽤top 124 SET ROWCOUNT 1
25 SELECT @empid= empid, @firstname= firstname,@lastname= lastname FROM @temp;
26 UPDATE HR.Employees SET fullname= @firstname+' '+@lastname WHERE empid=@empid;27 SET ROWCOUNT 028
29 DELETE FROM @temp WHERE empid=@empid;30 END
使⽤临时表
临时表也可以实现表变量的功能,所以我们也可以使⽤临时表来实现这个需求,代码如下。
1 -- ⽅法3:使⽤临时表 2 -- 创建临时表
3 IF OBJECT_ID('tempdb.dbo.#tempemployees','U') IS NOT NULL DROP TABLE dbo.#tempemployees; 4 GO 5
6 SELECT empid,firstname,lastname 7 INTO dbo.#tempemployees 8 FROM HR.Employees 9 ORDER BY empid;10
11 --SELECT * FROM dbo.#tempemployees;12
13 -- 声明变量14 DECLARE
15 @empid AS INT,
16 @firstname AS NVARCHAR(10),17 @lastname AS NVARCHAR(20);18
19 WHILE EXISTS(SELECT empid FROM dbo.#tempemployees)20 BEGIN
21 -- 也可以使⽤top 122 SET ROWCOUNT 1
23 SELECT @empid= empid, @firstname= firstname,@lastname= lastname FROM dbo.#tempemployees;24 UPDATE HR.Employees SET fullname= @firstname+' '+@lastname WHERE empid=@empid;25 SET ROWCOUNT 026
27 DELETE FROM dbo.#tempemployees WHERE empid=@empid;28 END
当然,实现的效果都是⼀样的。
因篇幅问题不能全部显示,请点此查看更多更全内容
Copyright © 2019- pqdy.cn 版权所有 赣ICP备2024042791号-6
违法及侵权请联系:TEL:199 1889 7713 E-MAIL:2724546146@qq.com
本站由北京市万商天勤律师事务所王兴未律师提供法律服务