powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / FoxPro, Visual FoxPro [игнор отключен] [закрыт для гостей] / Журнал изменений
2 сообщений из 2, страница 1 из 1
Журнал изменений
    #33799948
no.exit | tex
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Есть база данных, в которой необходимо вести журнал изменений по полям. Так вот иногда при добавлении записи, почему-то в журнал информация о добавлении не записывается, т.е. добавили в две таблицы записи, например в 1-ю 2, а во 2-ю 10, в следующем порядке, сначала 1-у в 1-ю табл. потом 5 во 2-ю, далее опять 1-у в первую, и оставшиеся 5 во вторую. Так вот информация о добавлении, почему-то не проходит при добавлении 5 записей на первом шаге, т.е. во вторую таблицу, но по остальным все ок. Ниже приведен код.

Код: plaintext
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


...
Рейтинг: 0 / 0
Журнал изменений
    #33800367
no.exit | tex
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
В догонку. Хочу обощить все вышеизложенное. Записи добавляются в таблицы, но в момент добавления триггеры неправильно срабатывают, т.е. в журнал ничего не записывается 8( Либо выборки дают 0, хотя они все идут из таблицы tcenters, которая заполняется отдельно при настройке БД и в программе в ней изменяется только одно поле - уникальный ключ заказа. Либо вставка неудачная производиться в журнал, не пойму в чем дело, т.к. происходит это где-то на 1000 вставок.
...
Рейтинг: 0 / 0
2 сообщений из 2, страница 1 из 1
Форумы / FoxPro, Visual FoxPro [игнор отключен] [закрыт для гостей] / Журнал изменений
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]