|
19.06.2006, 14:55
#33799948
Ссылка:
Ссылка на сообщение:
Ссылка с названием темы:
|
|
|
|
Есть база данных, в которой необходимо вести журнал изменений по полям. Так вот иногда при добавлении записи, почему-то в журнал информация о добавлении не записывается, т.е. добавили в две таблицы записи, например в 1-ю 2, а во 2-ю 10, в следующем порядке, сначала 1-у в 1-ю табл. потом 5 во 2-ю, далее опять 1-у в первую, и оставшиеся 5 во вторую. Так вот информация о добавлении, почему-то не проходит при добавлении 5 записей на первом шаге, т.е. во вторую таблицу, но по остальным все ок. Ниже приведен код.
1. 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. 139. 140. 141. 142. 143. 144. 145. 146. 147. 148. 149. 150. 151. 152. 153. 154. 155. 156. 157. 158. 159. 160. 161. 162. 163. 164. 165. 166. 167. 168. 169. 170. 171. 172. 173. 174. 175. 176. 177. 178. 179. 180. 181. 182. 183. 184. 185. 186. 187. 188. 189. 190. 191. 192. 193. 194. 195. 196. 197. 198. 199. 200. 201. 202. 203. 204. 205. 206. 207. 208. 209. 210. 211. 212. 213. 214. 215. 216. 217. 218. 219. 220. 221. 222. 223. 224. 225. 226. 227. 228. 229. 230.
FUNCTION MainTrigger(c_TableName)
LOCAL ln_arrValue[ 1 ]
ln_arrValue( 1 )= 0
SELECT COUNT(centerid) FROM tcenters ;
WHERE source = .T. ;
INTO ARRAY ln_arrValue
IF(ln_arrValue( 1 )> 0 )
* проверка на курсор
IF (JUSTEXT(DBF()) = "TMP")
RETURN .T.
ENDIF
LOCAL lcAlias
IF TYPE("c_TableName")<>"C" OR EMPTY(m.c_TableName)=.T.
lcAlias = UPPER(JUSTSTEM(DBF()))
ELSE
lcAlias = UPPER(AllTrim(m.c_TableName))
ENDIF
LOCAL lc_returnval
lc_returnval = .F.
DO CASE
CASE Deleted()
lc_returnval = TRIGGERPROCESS(lcAlias,"D",dbid,recid) && вызов из триггера на удаление
CASE NVL(OldVal("Deleted()"),.T.)
lc_returnval = TRIGGERPROCESS(lcAlias,"A",dbid,recid) && вызов из триггера на вставку
OTHERWISE
lc_returnval = TRIGGERPROCESS(lcAlias,"M",dbid,recid) && вызов из триггера на модификацию
ENDCASE
ENDIF
RETURN lc_returnval
ENDFUNC
*<<>><<>><<>><<>><<>><<>><<>><<>><<>><<>><<>><<>><<>><<>><<>><<>><<>><<>>
*<<>><<>><<>><<>><<>><<>><<>><<>><<>><<>><<>><<>><<>><<>><<>><<>><<>><<>>
* основное тело триггера
* вх. параметры
* c_Table_name - имя таблицы
* c_Act - дествие произведенное оператором
* i_dbid - идентификатор базы данных (часть составного ключа)
* i_recid - идентификатор записи в таблице (часть составного ключа)
FUNCTION TRIGGERPROCESS(c_TableName,c_Act,i_dbid,i_recid)
LOCAL ln_DBID && идентификатор БД для записи
LOCAL ln_RecID && идентификатор номера записи
LOCAL lc_Act && A - добавлена, E - изменена, D - удалена
LOCAL lt_DateTime && дата и время изменения
LOCAL ln_State && тек. состояние записи
LOCAL lc_fldstate && строка, в кот. закодировано какие поля изменились
LOCAL ln_len && длина строки
LOCAL lc_fldname && имя поля
LOCAL lc_symbol && символ состояния поля == 1 -не изм, 2 -изм, 3 -доб.не изм, 4 -доб.изм.
LOCAL lc_OldDecimal && переменная установки среды
LOCAL lc_OldANSI && переменная установки среды - сравнивание строк в SQL запросах
LOCAL ln_fldindex
LOCAL ln_i
LOCAL ll_NotError
* инициализация
ln_DBID = m.i_dbid
ln_RecID = m.i_recid
lc_Act = m.c_Act
lt_DateTime = DATETIME()
ln_State = 0
lc_fldstate = GETFLDSTATE(- 1 ) && определяем какие поля изменились
ln_len = LEN(lc_fldstate) && определяем длину строки
ll_NotError = .T.
*=====================================
* установим переменные среды
lc_OldDecimal = SET("DECIMALS")
lc_OldANSI = SET("ANSI")
SET DECIMALS TO 0
SET ANSI ON
*=====================================
*=====================================
LOCAL lc_Error
LOCAL ll_NotError
ll_NotError = .T.
lc_Error=ON("ERROR")
ON ERROR ll_NotError = .F.
*=====================================
*============================================================================
* узнаем идентификатор БД, создавшей запись
LOCAL ln_arrCurrentDBID[ 1 ]
ln_arrCurrentDBID( 1 ) = 0
SELECT centerid FROM tcenters ;
WHERE tcenters.visible=.T. ;
INTO ARRAY ln_arrCurrentDBID
*============================================================================
* узнаем идентификатор таблицы, в которой были произведены изменения
LOCAL ln_arrCurrentTBLID[ 1 ]
ln_arrCurrentTBLID( 1 ) = 0
SELECT tableid FROM ttables ;
WHERE ALLTRIM(UPPER(tablename))=ALLTRIM(UPPER(m.c_TableName)) ;
INTO ARRAY ln_arrCurrentTBLID
*============================================================================
* проверка, является ди данная БД центральной
LOCAL ll_arrIsMainCenter[ 1 ]
ll_arrIsMainCenter( 1 ) = .F.
SELECT maincenter FROM tcenters ;
WHERE tcenters.visible=.T. ;
INTO ARRAY ll_arrIsMainCenter
*============================================================================
* массив с идентификаторами баз данных, с кот. произв. синхронизация
LOCAL ln_arrDBS[ 1 ]
ln_arrDBS( 1 ) = 0
IF(ll_arrIsMainCenter( 1 )) THEN
* является главным центром
SELECT centerid FROM tcenters ;
WHERE tcenters.maincenter = .F. ;
INTO ARRAY ln_arrDBS
ELSE
* является филиалом
SELECT centerid FROM tcenters ;
WHERE tcenters.maincenter = .T. ;
INTO ARRAY ln_arrDBS
ENDIF
*============================================================================
IF(lc_Act == "M") THEN
* цикл - определение измененных полей в записи
FOR ln_fldindex = 1 TO ln_len
lc_fldstate = RIGHT(lc_fldstate,ln_len - ln_fldindex) && удалили крайний левый символ
lc_symbol = LEFT(lc_fldstate, 1 ) && выделили крайний левый символ
lc_fldname = UPPER(FIELD(ln_fldindex)) && получили название поля в верхнем регистре
* возможные варианты значения lc_symbol
* lc_symbol == '1' - поле не изменилось
* lc_symbol == '2' - поле модифицировано
* lc_symbol == '3' - поле добавлено (запись только-что создана)
* lc_symbol == '4' - поле добавлено и модифицировано (запись только-что создана, а поле изменило свое значение)
IF(lc_symbol == '2') THEN && поле модифицировано
*=====================================
* проверка на присутствие дублирующих записей
UPDATE tjournal ;
SET act = "P",state = - 1 ;
WHERE tableid = ln_arrCurrentTBLID( 1 ) .AND. dbid = ln_DBID .AND. recid = ln_RecID .AND. fldname = lc_fldname
*=====================================
*=====================================
* вставка записи в журнал - таблица tjournal
FOR ln_i = 1 TO ALEN(ln_arrDBS)
INSERT INTO tjournal (tableid,dbid,recid,fldname,act,date,owncenterid,state,centerid) ;
VALUES (ln_arrCurrentTBLID( 1 ),ln_DBID,ln_RecID,lc_fldname,lc_Act,lt_DateTime,ln_arrCurrentDBID( 1 ),ln_State,ln_arrDBS(ln_i))
NEXT
*=====================================
ENDIF
NEXT
*=====================================
ELSE && запись удалена или добавлена
lc_fldname = "*" && изменению подверглись все поля
*=====================================
* проверка на присутствие дублирующих записей
UPDATE tjournal ;
SET act = "P",state = - 1 ;
WHERE tableid = ln_arrCurrentTBLID( 1 ) .AND. dbid = ln_DBID .AND. recid = ln_RecID
*=====================================
*=====================================
* вставка записи в журнал - таблица tjournal
FOR ln_i = 1 TO ALEN(ln_arrDBS)
INSERT INTO tjournal (tableid,dbid,recid,fldname,act,date,owncenterid,state,centerid) ;
VALUES (ln_arrCurrentTBLID( 1 ),ln_DBID,ln_RecID,lc_fldname,lc_Act,lt_DateTime,ln_arrCurrentDBID( 1 ),ln_State,ln_arrDBS(ln_i))
NEXT
*=====================================
ENDIF
IF(CURSORGETPROP('BUFFERING','tjournal')> 1 ) THEN
=TABLEUPDATE(.T.,.T.,"tjournal")
ENDIF
*=====================================
* востановим переменные среды
ON ERROR &lc_Error
IF(lc_OldANSI == "OFF") THEN
SET ANSI OFF
ENDIF
SET DECIMALS TO (lc_OldDecimal)
*=====================================
RETURN ll_NotError
ENDFUNC
|
|
|