我的SQL语言的查询做得并不好。但我可以用游标来实现之。实现之后才发现,无论多么复杂的查询,利用游标也都会更容易理解。虽然使用游标可能会牺牲一定的性能,但在硬件快速发展的今天,牺牲那么一点半点也未为不可。
以下是我使用游标进行查询的一个实例,其中应该使用临时表的地方因为没有创建成功,只好使用事先创建好的表,显得此段代码有些不足,希望能给大家作抛砖引玉之用。
这是一个在SBO中计算到期应收账款的应用,由于时间仓促,代码中没有太多注释,日后我会慢慢补上的。
代码:
1CREATE PROCEDURE TS_GetPayDay
2AS
3BEGIN
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]
93END
2AS
3BEGIN
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]
93END