SQL 循环语句几种写法
摘自:https://www.cnblogs.com/guorongtao/p/11939751.html
SQL 循环语句几种写法
1、正常循环语句
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
declare @orderNum varchar (255) create table #ttableName(id int identity(1,1),Orders varchar (255)) declare @n int ,@ rows int insert #ttableName(orders) select orderNum from pe_Orders where orderId<50 --select @rows=count(1) from pe_Orders select @ rows =@@rowcount set @n=1 while @n<=@ rows begin select @orderNum=OrderNum from PE_Orders where OrderNum=( select Orders from #ttableName where id=@n) print (@OrderNum) select @n=@n+1 end drop table #ttableName |
2、不带事务的游标循环
1
2
3
4
5
6
7
8
9
10
11
12
13
|
declare @orderN varchar (50) --临时变量,用来保存游标值 declare y_curr cursor for --申明游标 为orderNum select orderNum from pe_Orders where orderId<50 open y_curr --打开游标 fetch next from Y_curr into @orderN ----开始循环游标变量 while(@@fetch_status=0) ---返回被 FETCH 语句执行的最后游标的状态,而不是任何当前被连接打开的游标的状态。 begin print (@orderN) update pe_Orders set Functionary+@orderN where orderNum=@orderN --操作数据库 fetch next from y_curr into @orderN --开始循环游标变量 end close y_curr --关闭游标 deallocate y_curr --释放游标 |
3、带事务的游标循环
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
|
select orderNum,userName,MoneyTotal into #t from pe_Orders po DECLARE @n int ,@error int --set @n=1 set @error=0 BEGIN TRAN --申明 开始事务 declare @orderN varchar (50),@userN varchar (50) --临时变量,用来保存游标值 declare y_curr cursor for --申明游标 为orderNum,userName select orderNum,userName from PE_Orders where Orderid<50 open y_curr fetch next from y_curr into @orderN,@userN while @@fetch_status = 0 BEGIN select isnull ( sum (MoneyTotal),0),orderNum from #t where username=@userN -- set @n=@n+1 set @error=@error+@@error --记录每次运行sql后 是否正确 0正确 fetch next from y_curr into @orderN,@userN END IF @error=0 BEGIN commit tran ---事务提交 END ELSE BEGIN ROLLBACK TRAN ---事务回滚 END close y_curr deallocate y_curr DROP TABLE #t |
4、if语句使用示例
1
2
3
4
5
6
7
8
9
10
|
declare @a int set @a=12 if @a>100 begin print @a end else begin print 'no' end |
5、while语句使用示例
1
2
3
4
5
6
7
8
|
declare @i int set @i=1 while @i<30 begin insert into test (userid) values (@i) set @i=@i+1 end -- 设置重复执行 SQL 语句或语句块的条件。只要指定的条件为真,就重复执行语句。可以使用 BREAK 和 CONTINUE 关键字在循环内部控制 WHILE 循环中语句的执行。 本条为以前从网上查找获取! |
6、临时表和try
1
2
3
4
5
6
7
8
|
-- 增加临时表 select * into #csj_temp from csj -- 删除临时表 用到try begin try -- 检测代码开始 drop table #csj_temp end try begin catch -- 错误开始 end catch |
7、游标循环读记录
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
|
declare @temp_temp int --declare @Cur_Name --@Cur_Name="aaa" --------------------------------- 创建游标 --Local(本地游标) DECLARE aaa CURSOR for select House_Id from House_House where Deleted=0 or deleted is null ----------------------------------- 打开游标 Open aaa ----------------------------------- 遍历和获取游标 fetch next from aaa into @temp_temp --print @temp_temp while @@fetch_status=0 begin --做你要做的事 select * from House_monthEnd where House_Id=@temp_temp fetch next from aaa into @temp_temp -- 取值赋给变量 -- end ----------------------------------- 关闭游标 Close aaa ----------------------------------- 删除游标 Deallocate aaa |
在数据库开发过程中,我们经常会碰到要遍历数据表的情形,一提到遍历表,我们第一印象可能就想到使用游标,使用游标虽然直观易懂,但是它不符合面向集合操作的原则,而且性能也比面向集合低。当然,从面向集合操作的角度出发,也有两种方法可以进行遍历表的操作,总结起来,遍历表有下面几种方法。
- 使用游标
- 使用表变量
- 使用临时表
我的需求是:针对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=0 BEGIN -- 操作 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.Employees 13 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 1 24 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 0 28 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 1 22 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 0 26 27 DELETE FROM dbo.#tempemployees WHERE empid=@empid; 28 END