我的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
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