Фиксация и отмена изменений в Visual FoxPro
« Назад Функция TABLEUPDATE([nRows [, lForce]] [, nWorkArea | cTableAlias] [, cErrorArray])фиксирует изменения, выполненные в буферизованной записи, таблице, курсоре или курсоре-адаптере, открытом в текущей или заданной рабочей области. Функция возвращает .T. при успешной фиксации изменений или .F. – в противном случае. Замечание. VFP по умолчанию устанавливает оптимистическую буферизацию записи для курсоров, ассоциированных с объектом CursorAdapter. Параметры: nRows – определяет вариант фиксации изменений в таблице или курсоре. Значения, принимаемые nRows, описаны в табл. 15.13. Таблица 15.13 Значения параметра nRows
Для совместимости с предыдущими версиями VFP параметр nRows также принимает .F. и .T. соответственно вместо 0 и 1. При задании 0 или 1 и возникновении ошибки таблица позиционируется на записи, в которой не могут быть выполнены изменения. Для определения причины ошибки можно употребить функцию AERROR( ). При работе с объектом CursorAdapter и задании для nRows 1 или 2 все изменения в курсоре, осуществленные как события объекта CursorAdapter, должны быть зафиксированы, если только не произошла ошибка при выполнении событий BeforeInsert, AfterInsert, BeforeDelete, AfterDelete, BeforeUpdate или AfterUpdate. VFP передает значение nRows событию BeforeCursorUpdate объекта CursorAdapter. lForce – задает, будет ли VFP перезаписывать изменения, выполненные в буфере записи, таблицы или курсора другим сетевым пользователем. Принимает следующие значения: F. – фиксирует изменения в таблице или курсоре начиная с его первой и завершая последней записью. Если встречается запись, модифицированная другим сетевым пользователем, то VFP генерирует ошибку, которую можно обработать ON ERROR-процедурой. Причем последняя может содержать TABLEUPDATE( ) с lForce = .T. Как альтернатива, если выполняется транзакция, ON ERROR-процедура может содержать команду ROLLBACK, для возврата таблицы или курсора в прежнее состояние; T. – перезаписывает изменения в таблице или курсоре, выполненные другим пользователем. Параметр lForce должен быть задан, если имеется параметр nWorkArea | cTableAlias. cErrorArray – имя массива, создаваемого, когда nRows = 2 и изменения не могут быть зафиксированы. Массив содержит номера записей, в которых не смогли быть зафиксированы изменения. Если параметр задается, то должны также присутствовать параметры lForce и nWorkArea | cTableAlias. Если произошла ошибка, отличная от ошибки фиксации изменений, то массив будет содержать один элемент, равный –1. Характер ошибки можно пределить, применив функцию AERROR( ). Если существует объект CursorAdapter, то VFP передает cErrorArray событию AfterCursorUpdate этого объекта. Функция TABLEUPDATE( ) фиксирует изменения в таблице или курсоре, лишь когда его свойство Buffering отлично от 1, то есть когда имеется буферизация записи или таблицы. Если буферизация отключена и выполнена функция TABLEUPDATE( ), то VFP сгенерирует ошибку. Управление буферизацией осуществляет функция CURSORSETPROP( ). При обновлении нескольких записей TABLEUPDATE( ) перемещает таблицу на последнюю обновленную запись. Замечание. Вызов TABLEUPDATE( ) для локальной таблицы или вида, не имеющего первичных полей (см. свойство KeyFieldList), генерирует для поиска обновляемой записи длинную опцию WHERE. По умолчанию в опции WHERE может быть до 40 полей. Если возникает ошибка SQL: Statement too long (Ошибка 1812), то следует либо использовать первичное поле, либо увеличить допустимую сложность опции WHERE, употребив SYS(3055). В качестве второго параметра функции следует взять величину, использующую 8 * FCOUNT( ): Sys(3055, Max(320, Min(2040, 8 * Fcount( )))) При употреблении объекта CursorAdapter выполняются следующие действия: TABLEUPDATE( ) оперирует только курсором, ассоциированным с объектом CursorAdapter; TABLEUPDATE( ) выполняет команды в соответствии с типом источника данных и командами, хранимыми свойствами InsertCmd, UpdateCmd и DeleteCmd; TABLEUPDATE( ) передает значение GETFLDSTATE(1) для каждой изменяемой записи следующим событиям объекта CursorAdapter: BeforeInsert, BeforeDelete, BeforeUpdate. С текущей записи объекта CursorAdapter можно переместиться в обработчиках следующих его событий: BeforeInsert, AfterInsert, BeforeDelete, AfterDelete, BeforeUpdate и AfterUpdate. Пример. Выполняются изменения в буферизованной таблице. close databases && && Создаем свободную таблицу Employee create table d:\Employee (LastName C(20)) && && При использовании буферизации set multilocks on && && Активизируем буферизацию таблицы CursorSetProp('Buffering', 5, 'Employee') && Добавляем в таблицу запись insert into Employee (LastName) values ('Сема') && && Фиксируем изменения TableUpdate && Просмотр результата browse last && && Меняем значение поля LastName replace LastName with 'Женя' && && Фиксируем изменения TableUpdate browse last && && Закрываем и удаляем таблицу Employee use delete file d:\Employee.dbf Функция TABLEREVERT([lAllRows [, nWorkArea | cTableAlias]])отменяет изменения, выполненные в буферизованной записи, таблице, курсоре или курсоре-адаптере, открытом в текущей или заданной рабочей области, и восстанавливает oldval-значения для удаленных таблиц и текущие, хранимые на диске значения для локальной таблицы или курсора. Функция возвращает число записей, изменения в которых отменены. Если TABLEREVERT( ) применяется с таблицей или курсором, используемым без буферизации, то VFP генерирует ошибку. Отмена изменений осуществляется до их фиксации, например функцией TABLEUPDATE( ). Фактически TABLEREVERT( ) восстанавливает содержимое буфера, которое пользователь может наблюдать, например, при выполнении BROWSE. Функция TABLEREVERT( ) не меняет положения файлового указателя. Параметр: lAllRows – определяет, все ли изменения таблицы или курсора будут отменены. Параметр имеет действие при буферизации таблицы. Тогда, если lAllRows = .F., то отменяются изменения сделанные в текущей записи; если lAllRows = .T., то отменяются все изменения. Если применяется буферизация записи, то параметр lAllRows игнорируется, все изменения текущей записи отменяются. Пример: close databases create table d:\Employee (LastName C(20)) && SET MULTILOCKS нужно установить в ON set multilocks on CursorSetProp('Buffering', 5, 'Employee') insert into Employee (LastName) values ('Сема') TableUpdate browse last && Покажет имя Сема && && Меняем значение поля LastName replace LastName with 'Женя' browse last && Покажет имя Женя && && Отменяем изменение записи TableRevert(.T.) browse last && Покажет имя Сема use delete file d:\Employee.dbf Функция CURVAL(cExpression [, nWorkArea | cTableAlias])возвращает значение поля (выражения), хранимое на диске, для текущей или заданной таблицы или удаленного источника. Тип возвращаемого значения определяется типом выражения, заданного cExpression. Параметр: cExpression – выражение, значение на диске которого возвращает CURVAL( ). Обычно cExpression – это имя поля или выражение, содержащее поля таблицы или удаленного источника данных. Если сравнить значения, возвращаемые CURVAL( ) и OLDVAL( ), то можно определить, изменил ли значение поля (с момента начала редактирования) другой сетевой пользователь или нет. Функции CURVAL( ) и OLDVAL( ) могут возвращать различные значения, только при оптимистической буферизации записи или таблицы. Замечание. При работе с видом в многопользовательском окружении значения, возвращаемые CURVAL( ), могут не отражать последние изменения, если прежде не использована функция REFRESH( ). Данные, возвращаемые видом, буферизуются и функция CURVAL( ) читает их из буфера. Для переноса в буфер изменений, произведенных другим пользователем, употребляется REFRESH( ). Пример. Вызываются функции CURVAL( ) и OLDVAL( ). close databases create table d:\Employee (LastName C(20)) set multilocks on CursorSetProp('Buffering', 5, 'Employee') insert into Employee (LastName) values ('Сема') ? CurVal('LastName') && Напечатает: .NULL. ? OldVal('LastName') && Напечатает: .NULL. TableUpdate ? CurVal('LastName') && Напечатает: "Сема" ? OldVal('LastName') && Напечатает: "Сема" && Меняем значение поля LastName и выводим его оригинальное значение replace LastName with 'Женя' ? CurVal('LastName') && Напечатает: "Сема" ? OldVal('LastName') && Напечатает: "Сема" && Фиксируем изменения TableUpdate ? CurVal('LastName') && Напечатает: "Женя" ? OldVal('LastName') && Напечатает: "Женя" use delete file d:\Employee.dbf Функция OLDVAL(cExpression [, nWorkArea | cTableAlias])возвращает оригинальное значение поля (выражения) для текущей или указанной таблицы. То есть возвращается значение, которое поле имело до изменения, причем это изменение не было зафиксировано. Результат возвращается для текущей записи. Тип возвращаемого значения определяется типом выражения, заданного cExpression. Параметр: cExpression – выражение, оригинальное значение которого возвращает OLDVAL( ). Обычно cExpression – это имя поля или выражение, содержащее поля таблицы или удаленного источника данных. Если таблица базы данных или курсор имеет правило проверки или триггер, то OLDVAL( ) не требует, чтобы была установлена буферизация записи или таблицы. В противном случае при отсутствии буферизации генерируется ошибка. Если установлена буферизация записи и файловый указатель смещен с изменой записи на другую или если выполнена функция TABLEUPDATE( ), или фиксация изменений вызвана другими действиями, например такими, как завершение транзакции, то поля будут обновлены и их оригинальные, существовавшие до обновления значения станут недоступны. Пример см. в описании функции CURVAL( ). Функция GETFLDSTATE(cFieldName | nFieldNumber [, nWorkArea | cTableAlias])возвращает число или .NULL., означающее статус изменения значения поля текущей записи или статус ее удаления. Результат возвращается для текущей или заданной параметром nWorkArea | cTableAlias таблицы. Функция GETFLDSTATE( ) употребляется, когда активизирована буферизация записи или таблицы. Смысл результатов функции описан в табл. 15.14. Таблица 15.14 Результаты функции GETFLDSTATE( ) и параметр nFieldState функции SETFLDSTATE( )
Параметры: cFieldName | nFieldNumber – имя или номер поля, для которого возвращается результат. Номер поля можно определить, воспользовавшись командой DISPLAY STRUCTURE или функцией FIELD( ). Если параметр nFieldNumber = –1, функция вернет строку, содержащую статусы изменения или удаления всех полей записи таблицы или курсора. Например, если таблица имеет 4 поля и изменено значение первого поля, то ? GetFLDState(–1) напечатает 12111 Первая единица результата говорит о том, что статус удаления записи сохранен, последующие 4 символа строки характеризуют статусы изменения полей текущей записи таблицы. Если nFieldNumber = 0, то функция вернет статус удаления текущей записи таблицы или курсора. Замечание. Простановка и последующее снятие пометки удаления переведут запись в ее первоначальное состояние, однако GETFLDSTATE( ) вернет результат, означающий, что статус удаления записи изменен. Статус изменения будет зафиксирован GETFLDSTATE( ) как при явном, так и неявном изменении значения поля. Явное изменение вызывается, например, командой REPLACE или INSERT INTO, неявное происходит в результате подстановки в добавленной записи значения по умолчанию (если таковое имеется). Пример 1: close databases open database d:\HomeLibrary\HomeLibrary.dbc use Authors select Authors set multilocks on && && Активизируем буферизацию таблицы CursorSetProp('Buffering', 5, 'Authors') && ? GetFLDState("Author") && Напечатает: 1 && && Изменяем значения поля Author первой записи таблицы replace Author with Proper(Author) ? GetFLDState("Author") && Напечатает: 2 Пример 2. Функция GETFLDSTATE( ) вызывается после добавления записи для поля State, имеющего значение по умолчанию, и поля Cust_id, его не имеющего. close databases set multilocks on create database d:\Example create table Customer (Cust_id C(6), State C(2) default "FL") && Активизируем буферизацию таблицы CursorSetProp('Buffering', 5, 'Customer') append blank ? GetFLDState ("State") && Напечатает: 4 ? GetFLDState("Cust_id") && Напечатает: 3 browse last close databases delete databases d:\Example Функция SETFLDSTATE(cFieldName | nFieldNumber, nFieldState
|