Level Extreme platform
Subscription
Corporate profile
Products & Services
Support
Legal
Français
Buffered table versus not buffered table
Message
General information
Forum:
Visual FoxPro
Category:
Other
Environment versions
Visual FoxPro:
VFP 9 SP2
OS:
Windows XP SP2
Network:
Windows 2003 Server
Database:
Visual FoxPro
Miscellaneous
Thread ID:
01315862
Message ID:
01315888
Views:
19
Here why you should not use

REPLACE Table.Field WITH value

That is written by Marcia Akins, so all credits must go to her:


Marcia Akins:

...
However, if you are interested in why you were having this problem, here it is (originally from The Hacker's Guide to Visual FoxPro 3.0):

When “REPLACE” Doesn’t!

One of the most useful techniques in Visual FoxPro is the ability to update a table in a work area which is not currently selected. This allows us to write code like this:
SELECT source
IF target.field #
   REPLACE target.field WITH source.field
ENDIF
But have you ever had a situation when it just didn’t seem to work? Or when it worked in some situations but not in others? You open up the Debugger and walk through the process. You can see that the field you're copying from has the right value and that the REPLACE command gets executed, but the target field doesn't change. What gives?
The answer is that you've run into the dreaded "REPLACE at EOF()" problem. REPLACE, like many of the original xBase commands, is a “scoped” command. Scope is a set of four choices (ALL, REST, NEXT n, RECORD n) that determines what records are affected by a command. Each scoped command has a default scope. For non-destructive commands (like LIST, DISPLAY and BROWSE), the default is ALL. For destructive commands (like DELETE and REPLACE), the default is NEXT 1 to keep you from blowing away your data by accident.

What does this have to do with the update that's failing? You're using REPLACE and you only want to change one record. What's scope got to do with it? Scope applies to the current work area, which may not be the target of the REPLACE (in fact, surely isn't if you're having this problem). If the record pointer in the current work area is at EOF (end-of-file), no REPLACE occurs, because there's no field to be replaced. For example:
SELECT TableB
REPLACE TableA.Field1 WITH Field2
fails if TableB is at end-of-file.

When folks encounter this behavior for the first time, they usually holler "Bug! I found a bug!" but they're wrong. It's designed to work this way and it makes sense. If REPLACE could only update a single record and field at a time, this behavior wouldn't be necessary. But you can write a REPLACE like this:
REPLACE TableA.Field1 WITH Value1, ;
TableB.Field2 WITH Value2, ;
TableC.Field3 WITH Value3
Whose scope should apply in this case? The rule is always the same - the current work area. If you didn't have that rule, what would you do if one of the destination tables was at end-of-file - replace some and not the others? The rule means you don't do any of them, which feels right.

The situation can be even uglier. Suppose the REPLACE above had a NEXT 5 clause as well. What happens if you run out of records in one of the destination tables before you've processed 5 records? Do you go on with the rest? The rule as it stands is simple - if there are enough records in the current work area, the REPLACE goes through. If you reach end-of-file in the active work area, you stop replacing.
Arguably the original designers probably shouldn't have let you write a REPLACE like the one above - then, this whole issue would be moot. But they did and until Visual FoxPro introduced the concept of transactions, there was no way to deal with an incomplete process, so there needed to be a rule that worked in all situations. None of which keeps this from being terribly confusing.
The solution to this problem is simple. Use the IN clause of REPLACE to tell FoxPro to switch work areas on the fly. So, the first example in this section is better written as:
REPLACE Field1 WITH TableB.Field2 IN TableA
The multi-table replace above is better written as a series of REPLACEs, each one either SELECTing the right table first or using IN to choose the right work area. Wrap the whole thing in a transaction if it's appropriate.
Against Stupidity the Gods themselves Contend in Vain - Johann Christoph Friedrich von Schiller
The only thing normal about database guys is their tables.
Previous
Next
Reply
Map
View

Click here to load this message in the networking platform