1
sql server 2000 触发器,表同步更新的问题
2
有三个表,A ,B,C
3
A、B表中含有: A1,B1,C1 三个字段,
4
C 表中存放A、B表中的A1、B1、C1 的集合,
5
字段类型都为nvarchar(10),
6
当表A的数据被更新、删除、插入后要反映到C表。
7
当表B的数据被更新、删除、插入后要反映到C表。
8
假定A,B表中在a1,b1,c1上有唯一索引
9
10
11
这个问题如果纯属从理论来说,是很容易解决的,因为从要求可知,实质上C表存放的数据即为A、B表的并集。可以在A、B表上创建相同的trigger,一旦A、B表上有变化,比如插入、删除或更新时,即清空C表数据,然后把A、B表的数据union后插入C表中即可实现目的:)呵呵呵。。。
12
13
下面的trigger的实现原理是:
14
15
当A表插入数据时,检查C表中是否有A表将要插入的数据,如果无,则将这行数据插入到C表中,反之,则不需要操作。
16
17
当A表update时, 检查B表中是否有更新前这行数据,如果有,则C表中应该保留这行数据且把A表中更新后的数据也插入到C表中去。如果B表中没有A表更新前的这行数据且C表中没有A表更新后的这行数据,则需要用A表更新后的数据来更新C表中与A表更新前这行数据相同的数据;如果B表中没有A表更新的的这行数据且C表中有A表更新后的这行数据,则需要从C表中删除跟A表更新前相同的那行数据(因为更新A表后,A表和B表都没有A表更新前的那行数据了,则这行数据显然在C表中不应该再存在了)。
18
19
当A表中删除时,检查B表是否还存在A表要删除的这行数据,如果有,则不能删除C表中与A表要删除的数据相同的行。反之,则执行删除操作。
20
21
22
B表中的trigger跟A表中的原理相同。
23
24
25
CREATE TRIGGER SYNC_C_BY_A
26
ON A
27
AFTER INSERT,UPDATE,DELETE
28
AS
29
Declare @Dml TinyInt --1:Insert 2:Update 3:Delete
30
Declare @RowsD Int
31
Declare @RowsI Int
32
Declare @A1_D nvarchar(10)
33
Declare @B1_D Nvarchar(10)
34
Declare @C1_D Nvarchar(10)
35
--确定是哪一种dml操作
36
Select @RowsD=Count(*) From Deleted
37
Select @RowsI=Count(*) From Inserted
38
If @RowsD=0 And @RowsI=0
39
Goto Exit_
40
If @RowsD=0 And @RowsI>0
41
Set @Dml=1
42
Else
43
If @RowsD>0 And @RowsI>0
44
Set @Dml=2
45
Else
46
If @RowsD>0 And @RowsI=0
47
Set @Dml=3
48
IF @DML=1
49
BEGIN
50
--检查c表中是否已经有A表中新插入的数据行,如果没有,则也插入
51
IF NOT EXISTS(SELECT TOP 1 1 FROM c,inserted i where c.a1=i.a1 and c.b1=i.b1 and c.c1=i.c1)
52
insert into c select * from inserted
53
END
54
IF @DML=2
55
BEGIN
56
--检查B表中是否有A表中更新前的这行数据,如果有,则不需要更新C表中的数据,而是要把A表中更新后的这行数据插入到C表中
57
IF NOT EXISTS(SELECT TOP 1 1 FROM B,DELETED d where b.a1=d.a1 and b.b1=d.b1 and b.c1=d.c1)
58
BEGIN
59
--如果C表中不存在A表更新后的这行数据,则更新C表中跟A表更新前那行数据相同的数据
60
IF NOT EXISTS(SELECT TOP 1 1 FROM C,INSERTED I WHERE C.A1=I.A1 AND C.B1=I.B1 AND C.C1=I.C1)
61
BEGIN
62
UPDATE C SET A1=I.A1,B1=I.B1,C1=I.C1 FROM C,INSERTED I,DELETED D WHERE C.A1=D.A1 AND C.B1=D.B1 AND C.C1=D.C1
63
END
64
--如果C表中存在A表更新后的这行数据,则需要删除C表中跟A表更新前相同的那行数据
65
ELSE
66
BEGIN
67
SELECT @A1_D=A1,@B1_D=B1,@C1_D=C1 FROM DELETED
68
DELETE FROM C WHERE @A1_D=A1 AND @B1_D=B1 AND @C1_D=C1
69
END
70
END
71
ELSE
72
insert into c select * from inserted i where not exists(select 1 from c where i.a1=c.a1 and i.b1=c.b1 and i.c1=c.c1)
73
END
74
IF @DML=3
75
BEGIN
76
--如果B表中不存在A表要删除的这行数据,则需要从C表中删除这行数据
77
IF not exists(select top 1 1 from b,deleted d where b.a1=d.a1 and b.b1=d.b1 and b.c1=d.c1)
78
DELETE FROM C WHERE EXISTS(SELECT 1 FROM deleted d where c.a1=d.a1 and c.b1=d.b1 and c.c1=d.c1)
79
END
80
EXIT_:
81
82
CREATE TRIGGER SYNC_C_BY_B
83
ON B
84
AFTER INSERT,UPDATE,DELETE
85
AS
86
Declare @Dml TinyInt --1:Insert 2:Update 3:Delete
87
Declare @RowsD Int
88
Declare @RowsI Int
89
Declare @A1_D nvarchar(10)
90
Declare @B1_D Nvarchar(10)
91
Declare @C1_D Nvarchar(10)
92
--确定是哪一种dml操作
93
Select @RowsD=Count(*) From Deleted
94
Select @RowsI=Count(*) From Inserted
95
If @RowsD=0 And @RowsI=0
96
Goto Exit_
97
If @RowsD=0 And @RowsI>0
98
Set @Dml=1
99
Else
100
If @RowsD>0 And @RowsI>0
101
Set @Dml=2
102
Else
103
If @RowsD>0 And @RowsI=0
104
Set @Dml=3
105
IF @DML=1
106
BEGIN
107
--检查c表中是否已经有B表中新插入的数据行,如果没有,则也插入
108
IF NOT EXISTS(SELECT TOP 1 1 FROM c,inserted i where c.a1=i.a1 and c.b1=i.b1 and c.c1=i.c1)
109
insert into c select * from inserted
110
END
111
IF @DML=2
112
BEGIN
113
--检查B表中是否有A表中更新前的这行数据,如果有,则不需要更新C表中的数据,而是要把A表中更新后的这行数据插入到C表中
114
IF NOT EXISTS(SELECT TOP 1 1 FROM A,DELETED d where a.a1=d.a1 and a.b1=d.b1 and a.c1=d.c1)
115
BEGIN
116
--如果C表中不存在B表更新后的这行数据,则更新C表中跟b表更新前那行数据相同的数据
117
IF NOT EXISTS(SELECT TOP 1 1 FROM C,INSERTED I WHERE C.A1=I.A1 AND C.B1=I.B1 AND C.C1=I.C1)
118
BEGIN
119
UPDATE C SET A1=I.A1,B1=I.B1,C1=I.C1 FROM C,INSERTED I,DELETED D WHERE C.A1=D.A1 AND C.B1=D.B1 AND C.C1=D.C1
120
END
121
--如果C表中存在更新B表后的这行数据,则需要删除C表中跟B表更新前相同的那行数据
122
ELSE
123
BEGIN
124
SELECT @A1_D=A1,@B1_D=B1,@C1_D=C1 FROM DELETED
125
DELETE FROM C WHERE @A1_D=A1 AND @B1_D=B1 AND @C1_D=C1
126
End
127
128
END
129
ELSE
130
insert into c select * from inserted i where not exists(select 1 from c where i.a1=c.a1 and i.b1=c.b1 and i.c1=c.c1)
131
END
132
IF @DML=3
133
BEGIN
134
--如果A表中不存在B表要删除的这行数据,则需要从C表中删除这行数据
135
if not exists(select top 1 1 from a,deleted d where a.a1=d.a1 and a.b1=d.b1 and a.c1=d.c1)
136
DELETE FROM C WHERE EXISTS(SELECT 1 FROM deleted d where c.a1=d.a1 and c.b1=d.b1 and c.c1=d.c1)
137
END
138
EXIT_:

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

94

95

96

97

98

99

100

101

102

103

104

105

106

107

108

109

110

111

112

113

114

115

116

117

118

119

120

121

122

123

124

125

126

127

128

129

130

131

132

133

134

135

136

137

138
