|
|
|
Как проверить были изменения внесены или нет?
|
|||
|---|---|---|---|
|
#18+
Вообщем вопрос такой,в универе задание дали=) Есть база на SQL,к которой подключаются по фоксу и работают с помощью представлений (View).В этой базе хранится куча инфы,и когда проиходят изменения: добавление,удаление,изменение записи,то все это дело региструется в другой таблице(назовем её журнал изменений).Теперь если я не сделал никаких изменений и нажал кнопку запомнить,то журнале изменений, в которой регестрируются все действия, все равно это зафиксируется,хотя по сути я ничего не сделал. Мне надо найти функцию в фоксе,она по идеи должна быть,которая бы мне вернула ложь или истинну - были изменения или нет,чтобы используя её я вносил данные в журнал изменений или не вносил. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 07.10.2006, 11:57 |
|
||
|
Как проверить были изменения внесены или нет?
|
|||
|---|---|---|---|
|
#18+
GETFLDSTATE() CURVAL() OLDVAL() ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 07.10.2006, 14:19 |
|
||
|
Как проверить были изменения внесены или нет?
|
|||
|---|---|---|---|
|
#18+
Если можете немного поясните,что делать будет каждая функция? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 08.10.2006, 14:02 |
|
||
|
Как проверить были изменения внесены или нет?
|
|||
|---|---|---|---|
|
#18+
>Если можете немного поясните,что делать будет каждая функция? А Хелп почитать не судьба? Хотя с CURVAL(), OLDVAL() я поторопился - они возвращают сотвествено текущее значение в буферизированой таблице Фокса и старое значение буфера, соотвествено, и для вьюхи или курсорадаптера с SQL-сервера не работают. А вот GETFLDSTATE() возвращает признак модифицировалось ли каке либо поле таблицы или курсора: Returns a numeric value indicating if a field in a table or cursor has been modified or had a record appended, or if the deleted status of the current record has been changed. GETFLDSTATE(cFieldName | nFieldNumber [, cTableAlias | nWorkArea]) Parameters cFieldName| nFieldNumber Specifies the name of the field or the number of the field for which the modification status is returned. The field number nFieldNumber corresponds to the position of the field in the table or cursor structure. DISPLAY STRUCTURE or FIELD( ) can be used to determine a field's number. You can specify –1 for nFieldNumber to return a character string consisting of deletion and modification status values for all fields in the table or cursor. For example, if a table has five fields and only the first field has been changed, GETFLDSTATE( ) returns 121111. The 1 in the first position indicates the deletion status has not been changed. You can also include 0 for nFieldNumber to determine if the deletion status of the current record has changed since the table or cursor was opened. Note: Using GETFLDSTATE() only determines if the deletion status of the current record has changed. For example, if you mark a record for deletion and then recall it, GETFLDSTATE() indicates the deletion status has changed even though the record's deletion status has returned to its original state. Use DELETED() to determine the current deletion status of a record. cTableAlias Specifies the alias of the table or cursor for which the field modification or record deletion status is returned. nWorkArea Specifies the work area of the table or cursor for which the field modification or record deletion status is returned. If you do not specify an alias or work area, GETFLDSTATE( ) returns a value for a field in the currently selected table or cursor. Return Value Numeric, Character, or .NULL. Remarks The following table lists the character return values and the corresponding modification or deletion status. Return value Modification or deletion status 1 Field has not been modified or deletion status has not changed. 2 Field has been modified or deletion status has changed. 3 Field in an appended record has not been modified or deletion status has not changed for the appended record. 4 Field in an appended record has been modified or deletion status has changed for the appended record. .NULL. At EOF( ) Row or table buffering must first be enabled with CURSORSETPROP( ) for GETFLDSTATE( ) to operate on local tables. The modification or deletion status is returned for the table or cursor open in the currently selected work area if GETFLDSTATE( ) is issued without the optional cTableAlias or nWorkArea arguments. Any change in a field will cause GETFLDSTATE() to return a value showing that the field has been modified, whether the change is explicit or implicit. An example of an explicit modification would be including the field in a REPLACE or INSERT INTO command. An implicit modification occurs in a field that has a default value when any command is issued that adds a new record. Example 1 The following example demonstrates how you can use GETFLDSTATE( ) to determine if the contents of a field have changed. MULTILOCKS is set to ON, a requirement for table buffering. The customer table in the testdata database is opened, and CURSORSETPROP( ) is then used to set the buffering mode to optimistic table buffering (5). GETFLDSTATE( ) is issued to display a value (1) corresponding to the unmodified state of the cust_id field before it is modified. The cust_id field is modified with REPLACE, and GETFLDSTATE( ) is issued again to display a value (2) corresponding to the modified state of the cust_id field. TABLEREVERT( ) is used to return the table to its original state, and GETFLDSTATE( ) is issued again to display a value (1) corresponding to the original state of the cust_id field. Copy Code CLOSE DATABASES CLEAR SET MULTILOCKS ON && Allow table buffering OPEN DATABASE (HOME(2) + 'data\testdata') USE Customer && Open customer table =CURSORSETPROP("Buffering",5,"customer") && Enable table buffering * Get field state on original cust_id field and display state nState=GETFLDSTATE("cust_id") DO DisplayState WITH nState("Original") * Change field contents and display state REPLACE cust_id WITH "***" nState=GETFLDSTATE("cust_id") DO DisplayState WITH nState("After Replace") * Discard table changes and display state = TABLEREVERT(.T.) && Discard all table changes nState=GETFLDSTATE("cust_id") DO DisplayState WITH nState("After Revert") PROCEDURE DisplayState PARAMETER nState,cOperation DO CASE CASE nState=1 =MESSAGEBOX("Field has not been modified",0,cOperation) OTHERWISE =MESSAGEBOX("Field has been modified",0,cOperation) ENDCASE Example 2 The following example shows the difference in behavior between fields with and without default values. Copy Code SET MULTILOCKS ON CREATE DATABASE example CREATE TABLE customer (cust_id C(6),state C(2) DEFAULT "FL") CLOSE TABLES USE customer =CURSORSETPROP("Buffering",5,"customer") APPEND BLANK ?GETFLDSTATE("cust_id") && Returns 3, field in an appended record has && not been modified. ?GETFLDSTATE("state") && Returns 4, field in an appended record has && been modified. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 08.10.2006, 15:56 |
|
||
|
Как проверить были изменения внесены или нет?
|
|||
|---|---|---|---|
|
#18+
Surgeon2000Если можете немного поясните,что делать будет каждая функция? А Вы не могли бы пояснить Вашу логику работы? Итак, есть таблица на MS SQL сервере. Есть таблица-лог, в которой храняться все изменения сделанные в этой таблице. ГДЕ хранится эта таблица-лог? Там же на MS SQL или у клиента в файлах DBF? Если таблица-лог хранится на MS SQL, то совершенно не важно чем именно (каким способом) происходит модификация таблицы-источника. Это все решается через триггеры типа Update "навешанные" таблицу-источник. При любой модификации таблицы-источника сработает триггер Update. Далее уже в этом триггере делаешь анализ: а изменилось ли в действительности контролируемые значения или нет. Это решается через служебную таблицу inserted. Эта таблица существует только внутри тела триггеров. Ее структура совпадает со структурой таблицы на которую и наложен триггер. Содержимое - это только измененные (добавленные) записи. Есть еще служебная таблица deleted, которая содержит удаленные записи. Т.е. FoxPro тут вообще не при чем. Никаким боком. Не его это задача. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 08.10.2006, 17:53 |
|
||
|
Как проверить были изменения внесены или нет?
|
|||
|---|---|---|---|
|
#18+
Да вся база и все таблицы на SQL. Там и сейчас работают тригеры,они то как раз и добавляют в таблицу логов то что были изменения,так они же SQL-ные триггеры срабатывают даже когда ничего по сути не было изменено.Я так понимаю это происходит т.к. фоксу когда говорят запомнить(такая кнопочка есть в моем меню когда работаешь с таблицей ),то они берет это Remote View,т.е. то что в буфере,записывает в таблицу,хотя по сути данные те же и остались.К примеру я поковыряю таблицу,ну пусть я нажму кнопку редактировать и веду значение 5 вместо 10,потом передумаю и опять веду 10,а потом нажму запомнить.Данные не изменились, но фокс подумает что я поменял их и запишет,а так как он их запишет то и тригер сработает.Получается в таблицу логов записало что такой-то пользователь сделал в такое-то время изменения с записью номер такая-то.А на самом деле,данные остались теже!Вот и надо решить такую проблему,что данные если не меняются то и записывать не к чему... ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 08.10.2006, 23:06 |
|
||
|
Как проверить были изменения внесены или нет?
|
|||
|---|---|---|---|
|
#18+
Так я же и объясняю. Анализируй результат в триггере MS SQL. Т.е. сравнивай содержимое исходной таблицы и содержимое служебной таблицы inserted. Если для одной и той же записи (одного значения ключевого поля) нет изменений в остальных полях, то и нечего записывать эту запись в лог. С точки зрения FoxPro эту проблему тоже можно решить, но, по сути, тем же самым способом. Т.е. "в тупую" перебирая поля таблицы и сравнивая с их исходным значением (исходное значение берешь по OldVal()). Если все совпало, то делается откат буфера по TableRevert() для данной записи. Но на стороне FoxPro - это совершенно бессмысленное занятие. Более того, это занятие бессмысленно с любой точки зрения. Прикинь, какова вероятность такого события? Ну будет у тебя немного мусора. Ну и что? Стоит ли чистка незначительного количества записей таких героических усилий? Впрочем, в качестве учебного задания такое еще сойдет. Как решить, направление тебе указали. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 08.10.2006, 23:25 |
|
||
|
Как проверить были изменения внесены или нет?
|
|||
|---|---|---|---|
|
#18+
Не... тут ты не совсем прав!Смысл определеный есть,это не учебная база,а реальное приложение,пусть не великое,но оно на приличной фирме работает.И дали потому как мусор появлеятся,это не единичный случай. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 09.10.2006, 17:15 |
|
||
|
Как проверить были изменения внесены или нет?
|
|||
|---|---|---|---|
|
#18+
А сделать на уровне SQL я подумаю ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 09.10.2006, 17:15 |
|
||
|
Как проверить были изменения внесены или нет?
|
|||
|---|---|---|---|
|
#18+
Я подумываю насчет использования функции GETNEXTMODIFIED что вы думаете? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 11.10.2006, 21:16 |
|
||
|
Как проверить были изменения внесены или нет?
|
|||
|---|---|---|---|
|
#18+
GetNextModified() не решит твоей проблемы. Она просто укажет тебе, что в буфере есть изменения этой записи. А вот изменились ли действительно значения полей либо в них повторно записали те же значения на этот вопрос можно получить ответ только сравнивая измененные поля через CURVAL() и OLDVAL() как указывал ВладимирМ ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 12.10.2006, 18:21 |
|
||
|
Как проверить были изменения внесены или нет?
|
|||
|---|---|---|---|
|
#18+
GETFLDSTATE(-1) первая цифра в строке - что делали с записью последующие - если там '2' значит соответствующее поле трогали, если '1', то не трогали 111112111111 - запись существовала и потрогали 6 поле ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 12.10.2006, 18:42 |
|
||
|
Как проверить были изменения внесены или нет?
|
|||
|---|---|---|---|
|
#18+
КОгда я получу такой результат 111112111111 мне с считывать цифру для каждого поля при помощи функций деления нацело и взятия остатка? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 21.10.2006, 10:52 |
|
||
|
Как проверить были изменения внесены или нет?
|
|||
|---|---|---|---|
|
#18+
Surgeon2000КОгда я получу такой результат 111112111111 мне с считывать цифру для каждого поля при помощи функций деления нацело и взятия остатка? Я понимаю, что читать HELP для "настоящих программистов" - глубоко противно. Но хоть эксперимент провести самостоятельно можно? Посмотреть какого типа получится результат и что означают все эти циферки. Кстати, они меняются в диапазоне от 1 до 4 Код: 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. Физический порядок следования полей можно получить через функцию AFIELDS(). Номер строки полученного массива - это и есть порядковый номер поля. Также можно использовать функции FIELD() для получения имени поля по его порядковому номеру. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 21.10.2006, 20:31 |
|
||
|
Как проверить были изменения внесены или нет?
|
|||
|---|---|---|---|
|
#18+
Да хелп не самое приятное занятие читать,но я его почитал.На англицком.Из того че понял то понял... Теперь буду знать что массив. А вообще спасибо большое за помощь! ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 21.10.2006, 23:46 |
|
||
|
Как проверить были изменения внесены или нет?
|
|||
|---|---|---|---|
|
#18+
"массив" относился к функции AFILEDS(), а то, что возвращает GetFldState(-1) - это символьная строка. Однако можно использовать и прямое обращение ?GetFldState("MyField","MyTable") В этом случае будет возвращено число, определяющее статус изменений для данного поля. Русский HELP по VFP3 есть в сети. Можно скачать, например, отсюда http://vfp.narod.ru/Briefcase/Briefcase.htm Там есть про GetFldState() Кроме того, уже близок к завершению проект перевода на русский язык HELP по VFP9. Скорее всего, его закончат где-то к новому году. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 22.10.2006, 12:36 |
|
||
|
Как проверить были изменения внесены или нет?
|
|||
|---|---|---|---|
|
#18+
А вот русский хелп по 9-му меня спасет! ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 22.10.2006, 16:59 |
|
||
|
Как проверить были изменения внесены или нет?
|
|||
|---|---|---|---|
|
#18+
Я все-такие одно не понял. Я беру сначала функцию GETNEXTMODIFIED(0,имя таблицы) так я проверяю были ли вообще изменения.Если были,то GETNEXTMODIFIED вернет номер первой измененной записи в таблице. Затем я в строковую переменную считываю значения,функцией GETFLDSTATE("имя таблицы",номер записи полученный от GETNEXTMODIFIED) А если у меня изменено несколько записей то так мне функция выдаст состояние строки номер которой я задал или всех последующих строк которые идут начиная с этой?Это все-таки char массив будет или что? Если можно привидите пример работы с результатом,например вернуло мне 111112111111 как я с цифирками обращаться могу?<--Это для меня самое главное. Просто моя идея такая,я беру при помощи GETNEXTMODIFIED номер каждой последующей измененной записи.Потом я расчитываю, что зная номер записи, GETFLDSTATE мне вернет её состояние.Если там появляются кроме 1 например 2,то мне надо проверить были ли реальные изменения или нет.Я это делаю при помощи CURVAL OLDVAL.Если изменения были то все я это дело останавливаю и произвожу запись из вьшек в таблицы,иначе пока до конца не дойду. Не хочется в тупую сравнивать штук 30 полей записи.А сравнить только те которые являются "подозрительными" на изменения. Я уточню,там скорее всего в этом месте я работаю с одной записью в таблице.Т.е. изменения могут быть в 1 записи и проверить надо одну. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 22.10.2006, 17:34 |
|
||
|
Как проверить были изменения внесены или нет?
|
|||
|---|---|---|---|
|
#18+
Напряг мозги и состряпал,тока не очень то и работает=) Если пользователь зашел и поменял значение на одно потом руками опять назад,то не срабатывает. SET MULTILOCKS ON =CURSORSETPROP("Buffering", 5, "rv_uz") IF (GETNEXTMODIFIED(0,"rv_uz") <> 0) LOCAL i as Integer LOCAL flag1 as Boolean flag1 = 0 FOR i=1 TO 100 IF FIELD(i,"rv_uz")='' EXIT ENDIF IF GetFldState(i,"rv_uz") <> 1 IF CURVAL(FIELD(i,"rv_uz"),"rv_uz") <> OLDVAL(FIELD(i,"rv_uz"),"rv_uz") flag1 = 1 EXIT ENDIF ENDIF ENDFOR IF flag1 = 0 если я оставлю SET MULTILOCKS ON =CURSORSETPROP("Buffering", 5, "rv_uz") IF (GETNEXTMODIFIED(0,"rv_uz") <> 0) а за ним пойдет метод который сохраняет,то когда пользователь зашел в режим редактирования,но ничего не трогал,все срабатывает. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 22.10.2006, 18:44 |
|
||
|
Как проверить были изменения внесены или нет?
|
|||
|---|---|---|---|
|
#18+
Странный Вы какой-то, Вам же предложили: скачайте русский HELP и наконец-то прочитайте как именно работают указанные функции. Там все по русски написано. Логика работы этих функций со времен VFP3 не изменилась. Могли добавиться новые параметры, но старая логика осталась неизменной. То, что Вы написали - вообще бессмысленно. При работе с курсором, полученным через SQLExec() или Remote View значения OldVal() и CurVal() всегда одинаковые OldVal() - это то значение, которое было в записи непосредственно перед началом изменения буфера CurVal() - это то значение, которое есть сейчас в dbf-таблице - источнике (но не в буфере!). Не на самом сервере, а в курсоре . Имеет смысл только для файл-сервера и прямой работы с DBF-таблицами. По сути, проверяет не изменилось ли значение другим пользователем, пока данный пользователь что-то там редактировал. Общие ошибки: 1) Глобальные настройки надо делать в главной (стартовой) процедуре или при инициализации формы. Делать настройку режима буферизации в момент сохранения просто бессмысленно. Все и так уже сохранено. 2) GetNextModified() - не перемещает указатель записи. Это значит, что если Вы модифицируете несколько записей одновременно, а потом перешли на НЕ измененную запись, то, хотя GetNextModified() и вернет номер изменной записи, но физического перемещения на эту измененную запись не произойдет. Останетесь там, где были. 3) Если на текущей форме пользователь изменяет только одну (текущую) запись, то зачем Вы вообще использовали GetNextModified()? Для одной (текущей) записи все гораздо проще Код: 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. Правда, такая проверка не сработает в случае использования значений NULL и специальных горячих клавиш, позволяющих записывать значение NULL в поля. В случае использования GetNextModified() нужен цикл, для организации перемещения по записям. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 22.10.2006, 20:09 |
|
||
|
Как проверить были изменения внесены или нет?
|
|||
|---|---|---|---|
|
#18+
Круто заработало,разобрал все, вопрос такой m.lnI,для чего m.? в программе тоже есть места с такого вида это что означает? Спасибо большое! ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 23.10.2006, 00:32 |
|
||
|
Как проверить были изменения внесены или нет?
|
|||
|---|---|---|---|
|
#18+
Surgeon2000вопрос такой m.lnI,для чего m.? в программе тоже есть места с такого вида это что означает? Что означает префикс (буква) "m." перед именем ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 23.10.2006, 00:47 |
|
||
|
|

start [/forum/topic.php?fid=41&fpage=229&tid=1590530]: |
0ms |
get settings: |
10ms |
get forum list: |
16ms |
check forum access: |
3ms |
check topic access: |
3ms |
track hit: |
55ms |
get topic data: |
12ms |
get forum data: |
3ms |
get page messages: |
122ms |
get tp. blocked users: |
1ms |
| others: | 247ms |
| total: | 472ms |

| 0 / 0 |
