我的SQL语言的查询做得并不好。但我可以用游标来实现之。实现之后才发现,无论多么复杂的查询,利用游标也都会更容易理解。虽然使用游标可能会牺牲一定的性能,但在硬件快速发展的今天,牺牲那么一点半点也未为不可。
以下是我使用游标进行查询的一个实例,其中应该使用临时表的地方因为没有创建成功,只好使用事先创建好的表,显得此段代码有些不足,希望能给大家作抛砖引玉之用。
这是一个在SBO中计算到期应收账款的应用,由于时间仓促,代码中没有太多注释,日后我会慢慢补上的。
代码:
1
CREATE PROCEDURE TS_GetPayDay
2
AS
3
BEGIN
4
DECLARE @DocNum NVARCHAR(100) --订单号
5
DECLARE @NumAtCard NVARCHAR(100) --合同号
6
DECLARE @CardName NVARCHAR(100) --客户
7
DECLARE @PayTimes INT --总付款次数
8
DECLARE @PayTime INT --付款次序
9
DECLARE @Prcnt INT --付款百分比
10
DECLARE @DocTotal NUMERIC --订单总额
11
12
DECLARE @DocDate DATETIME --单据日期
13
DECLARE @PayDay DATETIME --到期付款日期
14
DECLARE @PayDay1 DATETIME --
15
DECLARE @Months INT --间隔月份
16
DECLARE @Days INT --间隔天数
17
DECLARE @CurRow INT --当前行
18
DECLARE @CurCtg INT --当前付款条款
19
20
DELETE FROM [TS_Payment]
21
DELETE FROM [TS_Payment1]
22
DELETE FROM [TS_Payment2]
23
24
DECLARE Rows_cursor CURSOR
25
FOR
26
SELECT T0.DocEntry
27
FROM ORDR T0 ORDER BY T0.DocEntry
28
OPEN Rows_cursor;
29
FETCH NEXT FROM Rows_cursor INTO @CurRow;
30
WHILE(@@FETCH_STATUS<>-1)
31
BEGIN
32
IF(@@FETCH_STATUS<>-2)
33
BEGIN
34
SET @DocNum=(SELECT DocNum FROM ORDR WHERE DocEntry=@CurRow);
35
SET @NumAtCard=(SELECT NumAtCard FROM ORDR WHERE DocEntry=@CurRow);
36
SET @DocDate=(SELECT DocDate FROM ORDR WHERE DocEntry=@CurRow);
37
SET @CardName=(SELECT CardName FROM ORDR WHERE DocEntry=@CurRow);
38
SET @DocTotal=(SELECT DocTotal FROM ORDR WHERE DocEntry=@CurRow);
39
40
INSERT INTO [TS_Payment1](DocNum,NumAtCard,CardName,DocTotal)
41
VALUES(@DocNum,@NumAtCard,@CardName,@DocTotal)
42
43
SET @PayTimes=(SELECT InstNum FROM OCTG WHERE GroupNum=
44
(SELECT GroupNum FROM ORDR WHERE DocEntry=@CurRow));
45
DECLARE Ctg_cursor CURSOR
46
FOR
47
SELECT T1.IntsNo
48
FROM CTG1 T1
49
WHERE T1.CTGCode=(SELECT GroupNum FROM ORDR WHERE DocEntry=@CurRow)
50
OPEN Ctg_cursor;
51
FETCH NEXT FROM Ctg_cursor INTO @CurCtg;
52
WHILE(@@FETCH_STATUS<>-1)
53
BEGIN
54
IF(@@FETCH_STATUS<>-2)
55
BEGIN
56
--SELECT @CurCtg
57
SET @PayTime=(SELECT IntsNo FROM CTG1 WHERE IntsNo=@CurCtg
58
AND CTGCode
59
=(SELECT GroupNum FROM ORDR WHERE DocEntry=@CurRow));
60
SET @Prcnt=(SELECT InstPrcnt FROM CTG1 WHERE IntsNo=@CurCtg
61
AND CTGCode
62
=(SELECT GroupNum FROM ORDR WHERE DocEntry=@CurRow));
63
SET @Months=(SELECT InstMonth FROM CTG1 WHERE IntsNo=@CurCtg
64
AND CTGCode
65
=(SELECT GroupNum FROM ORDR WHERE DocEntry=@CurRow));
66
SET @Days=(SELECT InstDays FROM CTG1 WHERE IntsNo=@CurCtg
67
AND CTGCode
68
=(SELECT GroupNum FROM ORDR WHERE DocEntry=@CurRow));
69
70
SET @PayDay1=DATEADD(MONTH,@Months,@DocDate);
71
SET @PayDay=DATEADD(DAY,@Days,@PayDay1);
72
INSERT INTO [TS_Payment2](DocNum,NumAtCard,CardName,
73
DocTotal,PayTimes,PayTime,Prcnt,PayDay)
74
VALUES(@DocNum,@NumAtCard,@CardName,
75
@DocTotal,@PayTimes,@PayTime,@Prcnt,@PayDay)
76
END
77
FETCH NEXT FROM Ctg_cursor INTO @CurCtg;
78
END
79
CLOSE Ctg_cursor;
80
DEALLOCATE Ctg_cursor;
81
END
82
FETCH NEXT FROM Rows_cursor INTO @CurRow;
83
END
84
CLOSE Rows_cursor;
85
DEALLOCATE Rows_cursor;
86
87
DELETE FROM [TS_Payment1] WHERE DocNum IN(SELECT DocNum FROM [TS_Payment2])
88
89
INSERT INTO [TS_Payment]
90
SELECT * FROM [TS_Payment1]
91
UNION ALL
92
SELECT * FROM [TS_Payment2]
93
END
CREATE PROCEDURE TS_GetPayDay2
AS3
BEGIN 4
DECLARE @DocNum NVARCHAR(100) --订单号5
DECLARE @NumAtCard NVARCHAR(100) --合同号6
DECLARE @CardName NVARCHAR(100) --客户7
DECLARE @PayTimes INT --总付款次数8
DECLARE @PayTime INT --付款次序9
DECLARE @Prcnt INT --付款百分比10
DECLARE @DocTotal NUMERIC --订单总额11

12
DECLARE @DocDate DATETIME --单据日期13
DECLARE @PayDay DATETIME --到期付款日期14
DECLARE @PayDay1 DATETIME --15
DECLARE @Months INT --间隔月份16
DECLARE @Days INT --间隔天数17
DECLARE @CurRow INT --当前行18
DECLARE @CurCtg INT --当前付款条款19

20
DELETE FROM [TS_Payment]21
DELETE FROM [TS_Payment1]22
DELETE FROM [TS_Payment2]23

24
DECLARE Rows_cursor CURSOR25
FOR26
SELECT T0.DocEntry27
FROM ORDR T0 ORDER BY T0.DocEntry28
OPEN Rows_cursor;29
FETCH NEXT FROM Rows_cursor INTO @CurRow;30
WHILE(@@FETCH_STATUS<>-1)31
BEGIN32
IF(@@FETCH_STATUS<>-2)33
BEGIN34
SET @DocNum=(SELECT DocNum FROM ORDR WHERE DocEntry=@CurRow);35
SET @NumAtCard=(SELECT NumAtCard FROM ORDR WHERE DocEntry=@CurRow);36
SET @DocDate=(SELECT DocDate FROM ORDR WHERE DocEntry=@CurRow);37
SET @CardName=(SELECT CardName FROM ORDR WHERE DocEntry=@CurRow);38
SET @DocTotal=(SELECT DocTotal FROM ORDR WHERE DocEntry=@CurRow);39

40
INSERT INTO [TS_Payment1](DocNum,NumAtCard,CardName,DocTotal)41
VALUES(@DocNum,@NumAtCard,@CardName,@DocTotal)42
43
SET @PayTimes=(SELECT InstNum FROM OCTG WHERE GroupNum=44
(SELECT GroupNum FROM ORDR WHERE DocEntry=@CurRow));45
DECLARE Ctg_cursor CURSOR46
FOR 47
SELECT T1.IntsNo 48
FROM CTG1 T149
WHERE T1.CTGCode=(SELECT GroupNum FROM ORDR WHERE DocEntry=@CurRow)50
OPEN Ctg_cursor;51
FETCH NEXT FROM Ctg_cursor INTO @CurCtg;52
WHILE(@@FETCH_STATUS<>-1)53
BEGIN54
IF(@@FETCH_STATUS<>-2)55
BEGIN56
--SELECT @CurCtg57
SET @PayTime=(SELECT IntsNo FROM CTG1 WHERE IntsNo=@CurCtg 58
AND CTGCode59
=(SELECT GroupNum FROM ORDR WHERE DocEntry=@CurRow)); 60
SET @Prcnt=(SELECT InstPrcnt FROM CTG1 WHERE IntsNo=@CurCtg61
AND CTGCode62
=(SELECT GroupNum FROM ORDR WHERE DocEntry=@CurRow)); 63
SET @Months=(SELECT InstMonth FROM CTG1 WHERE IntsNo=@CurCtg 64
AND CTGCode65
=(SELECT GroupNum FROM ORDR WHERE DocEntry=@CurRow));66
SET @Days=(SELECT InstDays FROM CTG1 WHERE IntsNo=@CurCtg 67
AND CTGCode68
=(SELECT GroupNum FROM ORDR WHERE DocEntry=@CurRow));69

70
SET @PayDay1=DATEADD(MONTH,@Months,@DocDate);71
SET @PayDay=DATEADD(DAY,@Days,@PayDay1);72
INSERT INTO [TS_Payment2](DocNum,NumAtCard,CardName,73
DocTotal,PayTimes,PayTime,Prcnt,PayDay)74
VALUES(@DocNum,@NumAtCard,@CardName,75
@DocTotal,@PayTimes,@PayTime,@Prcnt,@PayDay)76
END77
FETCH NEXT FROM Ctg_cursor INTO @CurCtg;78
END79
CLOSE Ctg_cursor;80
DEALLOCATE Ctg_cursor;81
END82
FETCH NEXT FROM Rows_cursor INTO @CurRow;83
END84
CLOSE Rows_cursor;85
DEALLOCATE Rows_cursor;86

87
DELETE FROM [TS_Payment1] WHERE DocNum IN(SELECT DocNum FROM [TS_Payment2])88

89
INSERT INTO [TS_Payment]90
SELECT * FROM [TS_Payment1]91
UNION ALL 92
SELECT * FROM [TS_Payment2]93
END