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

3

4

5

6

7

8

9

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

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93
