TableUpdate(), TableRevert()
These functions commit or discard changes to buffered data.
Usage |
lSuccess = TableUpdate( [ lAll | nUpdateWhat [, lForce [, cAlias | nWorkArea [, ErrorRecordsArray ] ] ] ] ) nAffected = TableRevert( [ lAll [, cAlias | nWorkArea ] ] ) |
Parameter |
Value |
Meaning |
lAll |
Logical |
Should we update or revert all records or just the current record? Relevant only when using table buffering. |
nUpdateWhat |
0 |
Update only the current row. |
1 |
If table buffering is on, update all rows. If row buffering is on, update the current row. Give up as soon as an error occurs, leaving whatever has already been updated changed. |
|
2 |
Same as 1, except if an error occurs, log it in ErrorRecordsArray and continue. |
|
lForce |
Logical |
Should we insist on our changes going through, even if others have changed the record in the meantime? |
cAlias |
Character |
Commit or discard changes for table cAlias. |
Omitted |
If nWorkArea is also omitted, commit or discard changes for the table in the current work area. |
|
nWorkArea |
Numeric |
The work area containing the table to have changes committed or discarded. |
Omitted |
If cAlias is also omitted, commit or discard changes for the table in the current work area. |
|
ErrorRecordsArray |
Array Name |
If nUpdateWhat is 2, contains a list of record numbers for which the update was unsuccessful. |
lSuccess |
.T. |
All changes were successfully committed. |
.F. |
Some changes could not be committed. |
|
nAffected |
Numeric |
The number of records for which changes were discarded. |
In VFP 3, when you use table buffering, you have to either commit or revert changes before you can close the form. Otherwise, you get an error message—fair enough. What isn't fair is that when you're using a private data session, the form goes ahead and closes, and leaves you with a data session labeled "Unknown" with the offending table still open. In fact, anything that prevents a table from closing (like a trigger failing) when you close the form causes the same problem. The moral is that you must be sure to either commit or revert changes as part of a form close. If you should get caught in this situation, you can go to the View window, choose the Unknown data session, select the open table, issue TableRevert(.T.), then close the table. Once you've closed every table in the Unknown data session (any relation to the Unknown Soldier?), the session goes away. |
This one isn't exactly a bug itself, but something that could bite you when you're not watching. It's possible to open a table whose header is corrupted by having the record count too low. When you add a new record to such a table, TableUpdate() returns .T., but the new record actually overwrites an existing record (because the record count indicates where to put it). Worse yet, the record count in the header doesn't seem to get properly updated in this setting, so you can add record after record and end up with only one new record. The best way to fix this kind of corruption is to PACK the table, which cleans up the table header. |
The original release of VFP 7 has a very nasty bug that makes it possible to violate and corrupt primary or candidate indexes. If you attempt a TableUpdate() and it fails due to error 1884 ("Uniqueness of index violated"), and then you attempt the same TableUpdate(), it succeeds the second time. That results in bad data in the table and a corrupt index. Not surprisingly, this bug was squashed in Service Pack 1. |
Example |
* The Click code for a Cancel button may be as simple as: =TableRevert() * For a Save button, there are several approaches. If you choose * to resolve conflicts first (see GETFLDSTATE() for one way to * do so for a single record), you can finish up with a call * to TableUpdate(): IF NOT TableUpdate(2, .T., ALIAS(),aSaveErrors) * Force changes on all rows, but just in case, track * any errors in an array. * You'll want something a little more sophisticated here. WAIT WINDOW "Unexpected problem with " + ; ALEN(aSaveErrors,1) + " records" ENDIF |
See Also |
Buffering, CurVal(), GetFldState(), GetNextModified(), OldVal() |