T-SQL 编程之结果集循环处理

1.游标循环

在关系数据库中,循环遍历数据的方式,可以通过游标来实现。

通常查询数据时都是以集合的方式进行的,然而游标打破了这一规则,可以进行逐行的查询;


 

T-SQL中,游标的生命周期由5部分组成,也就是说,要使用游标,必须执行以下这5个步骤:

1).定义游标

2).打开游标

3).使用游标

4).关闭游标

5).释放游标

 

简单示例:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
-- 检查临时表
 
IF  NOT object_id(‘TempDB.. # temp ’)  IS NULL
 
Begin
 
DROP TABLE TempDB..#Temp_table
 
End
 
 
-- 创建临时表
 
Create Table TempDB..#Temp_table (a  int , b  int )
 
 
 
-- 1. 定义游标
 
Declare cur1  CURSOR FOR
 
-- 游标查询数据集合
 
Insert into TempDB..#Temp_table
 
        Select 1, 2
 
 
Declare @i  int ,
 
 
-- 2.打开游标
 
OPEN cur
 
 
-- 3.使用游标
 
FETCH cur   INTO @i
 
While @@fetch_status = 0
 
Begin
 
     Print @i
 
 
     -- 下一条记录
 
     Fetch cur  into @i
 
End
 
 
-- 4. 关闭游标
 
Close cur
 
IF  NOT object_id(‘TempDB.. # temp ’)  IS NULL
 
Gegin
 
DROP TABLE TempDB..#Temp_table
 
End
 
 
-- 5. 释放游标
 
Deallocate cur

 

2.游标嵌套循环

对于游标的嵌套循环操作,在 “使用游标” 的周期时,再次执行一次游标循环:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
Create Table # temp (a  int ,b  int )
 
Insert Into # temp
 
        Select 1,2
 
Insert Into # temp
 
        Select 3,4
 
 
Select From # temp
 
 
Declare @i  int ,  @j  int
 
Declare cur1  Cursor For
 
      Select From # temp
 
Open cur1
 
Fetch cur1  into @i
 
WHILE @@fetch_status =0
 
Begin
 
        Select 'cur1:' , @i
 
        -- 内部循环
 
        Declare cur2  Cursor For
 
                Select From # temp
 
        Open cur2
 
        Fetch cur2  into @j
 
        WHILE @@fetch_Status =0
 
        Begin
 
              Select 'cur2:' ,@j
 
              Fetch cur2  into @j
 
        End
 
        Close cur2
 
        Deallocate cur2
 
Fetch cur1  into @i
 
End
 
 
Close cur1
 
Drop Table # temp
 
Deallocate cur1

 

3. 游标的优缺点

优点:逐行查询,优化数据处理,方便开发人员

缺点:性能上,消耗更多的内存,减少可用的并发,占用带宽,锁定资源,代码量大,可读性差;

不难看出,使用游标的缺点多于其优点,但其存在必定有其作用,SQL Server中的系统多处使用游标检索、处理数据。

在开发中,可以将游标作为一种备用,当我们穷尽了 While循环,子查询,临时表,表变量,自建函数或其他方式扔来无法实现某些查询的时候,使用游标实现

 

4. 避免使用游标的处理方法

可以通过While循环、变量、临时表等方式,来避免使用游标。

这里有两种方法可以避免使用游标,如若还不能满足需求,就只能回头使用游标了。

 

第一种方法(常用方法):

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
-- 定义一个表变量(必须包含自增长的ID主键)
 
Declare @tempTable  table (ID  int identity(1,1), unitID  int , unitState  int , partID  bigint )
 
Insert into @tempTable
 
        Select distinct u.id, u.UnitStateID, u.PartID
 
        From ffUnit u
 
        Join ffUnitDetail ud  On u.id =  ud.unitID
 
        Where ud.InmostPackageID = @packageID
 
 
 
--  定义累加变量
 
Declare @i  int
 
Declare @j  int
 
Set @i = 0
 
Select @j =  MAX (ID)  From @tempTable
 
 
WHILE @i < @j
 
Begin
 
       Set @i = @i + 1
 
       Set @UnitID =  null
 
       Set @CurrUnitStateID =  null
 
       Set @PartID =  null
 
       Select @UnitID = unitID, @CurrUnitStateID = unitState, @PartID = partID
 
              From @tempTable
 
              Where ID = @i
 
       Drop Table @ tempTable  Where ID = @i
 
End
 
Drop Table @tempTable

 

第二种方法(使用ROW_NUMBER函数):

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
Declare @row  int
 
Declare @number  int ;
 
Declare @Temp_table  Table ( [ name ] nvarchar(200))
 
Select ROW_NUMBER() OVER ( ORDER BY [ Name ] )  AS number,[ name INTO #nn1
  
        From dbo.code
 
Select @number =  MAX (number)  From #nn1
 
Set @row = 1
 
WHILE (@row <= @number)
 
Begin
 
      Inert  Into @Temp_table
 
            Select [ name From #nn1
 
                   Where number = @row
 
      Set @row = @row + 1
 
END
 
DROP TABLE #nn1

 

 

参考文章:

http://www.2cto.com/database/201304/200084.html

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值