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

来源:互联网 发布:淘宝上如何买衣服 编辑:程序博客网 时间:2024/05/17 20:28

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 NOTobject_id(‘TempDB.. #temp’) ISNULL
 
Begin
 
DROPTABLE TempDB..#Temp_table
 
End
 
 
-- 创建临时表
 
CreateTable TempDB..#Temp_table (a int, b int)
 
 
 
-- 1. 定义游标
 
Declarecur1 CURSORFOR
 
-- 游标查询数据集合
 
Insertinto TempDB..#Temp_table
 
       Select1, 2
 
 
Declare@i int,
 
 
-- 2.打开游标
 
OPENcur
 
 
-- 3.使用游标
 
FETCHcur  INTO@i
 
While @@fetch_status = 0
 
Begin
 
    Print @i
 
 
    -- 下一条记录
 
    Fetchcur into@i
 
End
 
 
-- 4. 关闭游标
 
Closecur
 
IF NOTobject_id(‘TempDB.. #temp’) ISNULL
 
Gegin
 
DROPTABLE TempDB..#Temp_table
 
End
 
 
-- 5. 释放游标
 
Deallocatecur

 

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
CreateTable #temp(a int,b int)
 
InsertInto #temp
 
       Select1,2
 
InsertInto #temp
 
       Select3,4
 
 
SelectFrom#temp
 
 
Declare@i int,  @j int
 
Declarecur1 CursorFor
 
     SelectFrom#temp
 
Opencur1
 
Fetchcur1 into@i
 
WHILE @@fetch_status =0
 
Begin
 
       Select'cur1:', @i
 
       -- 内部循环
 
       Declarecur2 CursorFor
 
               SelectFrom#temp
 
       Opencur2
 
       Fetchcur2 into@j
 
       WHILE @@fetch_Status =0
 
       Begin
 
             Select'cur2:',@j
 
             Fetchcur2 into@j
 
       End
 
       Closecur2
 
       Deallocatecur2
 
Fetchcur1 into@i
 
End
 
 
Closecur1
 
DropTable #temp
 
Deallocatecur1

 

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 intidentity(1,1), unitID int, unitState int, partID bigint)
 
Insertinto @tempTable
 
       Selectdistinct u.id, u.UnitStateID, u.PartID
 
       FromffUnit u
 
       JoinffUnitDetail ud Onu.id =  ud.unitID
 
       Whereud.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
 
             WhereID = @i
 
      DropTable @ tempTable WhereID = @i
 
End
 
DropTable @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))
 
SelectROW_NUMBER() OVER (ORDERBY [Name] ) ASnumber,[nameINTO#nn1
  
       Fromdbo.code
 
Select@number = MAX(number) From#nn1
 
Set@row = 1
 
WHILE (@row <= @number)
 
Begin
 
     Inert Into@Temp_table
 
           Select[nameFrom#nn1
 
                  Wherenumber = @row
 
     Set@row = @row + 1
 
END
 
DROPTABLE #nn1

 

 

参考文章:

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

 

0 0
原创粉丝点击