Dear all,

The code beneath generates an error in VFP9. In VFP8 it runs fine.

The purpose of the original code is to store data from a view into the
database. The sample code doesn't really make sense anymore. We
stripped the code down to its bare minimum. It's just a way to show
the error.

We don't think this code is illegal. So, is there a bug in VFP9?

Regards,

Roel, Bas and Benno.



*=========== BEGIN CODE ============================

CREATE DATABASE database
OPEN DATABASE database

CREATE TABLE test (FIELD_KEY I, FIELD_DATA I)
INSERT INTO TEST (FIELD_KEY, FIELD_DATA) VALUES (0, 0)

CREATE SQL VIEW MYVIEW AS SELECT * FROM test
USE MYVIEW IN 1

CURSORSETPROP("buffering", 5, 1)
CURSORSETPROP("keyfieldlist", "FIELD_KEY", 1)
CURSORSETPROP("UpdatableFieldList", "FIELD_KEY, FIELD_DATA", 1)

REPLACE FIELD_DATA WITH 1 IN 1
SAVE_VIEW()

APPEND BLANK IN 1
REPLACE FIELD_KEY WITH 1 IN 1
SAVE_VIEW()

PROCEDURE SAVE_VIEW()
LOCAL nRecno

nRecno = GETNEXTMODIFIED(0, 1)
BEGIN TRANSACTION
GOTO (nRecno) IN 1
IF (nRecno > 0)
REFRESH(1, 0, 1)
CURVAL("FIELD_DATA", 1)
ENDIF
TABLEUPDATE(0, .F., 1)
END TRANSACTION
ENDPROC

Re: Transaction problem in VFP9 by Anders

Anders
Thu Feb 10 20:41:52 CST 2005

Curiously the error doesn't occur if the line with CURVAL() in the Save_view
function is commented out.
The added record doesn't get saved to Test in any case.
-Anders


"Benno" <b.richters@ogdsoftware.nl> wrote in message
news:a68bd7ff.0502100941.64caa2e0@posting.google.com...
> Dear all,
>
> The code beneath generates an error in VFP9. In VFP8 it runs fine.
>
> The purpose of the original code is to store data from a view into the
> database. The sample code doesn't really make sense anymore. We
> stripped the code down to its bare minimum. It's just a way to show
> the error.
>
> We don't think this code is illegal. So, is there a bug in VFP9?
>
> Regards,
>
> Roel, Bas and Benno.
>
>
>
> *=========== BEGIN CODE ============================
>
> CREATE DATABASE database
> OPEN DATABASE database
>
> CREATE TABLE test (FIELD_KEY I, FIELD_DATA I)
> INSERT INTO TEST (FIELD_KEY, FIELD_DATA) VALUES (0, 0)
>
> CREATE SQL VIEW MYVIEW AS SELECT * FROM test
> USE MYVIEW IN 1
>
> CURSORSETPROP("buffering", 5, 1)
> CURSORSETPROP("keyfieldlist", "FIELD_KEY", 1)
> CURSORSETPROP("UpdatableFieldList", "FIELD_KEY, FIELD_DATA", 1)
>
> REPLACE FIELD_DATA WITH 1 IN 1
> SAVE_VIEW()
>
> APPEND BLANK IN 1
> REPLACE FIELD_KEY WITH 1 IN 1
> SAVE_VIEW()
>
> PROCEDURE SAVE_VIEW()
> LOCAL nRecno
>
> nRecno = GETNEXTMODIFIED(0, 1)
> BEGIN TRANSACTION
> GOTO (nRecno) IN 1
> IF (nRecno > 0)
> REFRESH(1, 0, 1)
> CURVAL("FIELD_DATA", 1)
> ENDIF
> TABLEUPDATE(0, .F., 1)
> END TRANSACTION
> ENDPROC


RE: Transaction problem in VFP9 by Mark

Mark
Mon Feb 14 09:01:09 CST 2005

Hi Benno,
Next Time, you might want to read more carefully your helpfiles.
I have changed your code in order to work - see below.

hth
Mark

SET MULTILOCKS ON
CREATE DATABASE database
OPEN DATABASE database

CREATE TABLE test (FIELD_KEY I, FIELD_DATA I)
INSERT INTO TEST (FIELD_KEY, FIELD_DATA) VALUES (0, 0)
CURSORSETPROP("buffering", 3, "Test")

CREATE SQL VIEW MYVIEW AS SELECT * FROM test
USE MYVIEW IN 0
SELECT MyView

CURSORSETPROP("buffering", 5, "MyView")
CURSORSETPROP("keyfieldlist", "FIELD_KEY", "MyView")
CURSORSETPROP("UpdatableFieldList", "FIELD_KEY, FIELD_DATA", "MyView")
CURSORSETPROP("Tables","Test")
CURSORSETPROP("SendUpdates",.T.)

REPLACE FIELD_DATA WITH 1 IN MyView
SAVE_VIEW()

APPEND BLANK IN MyView
REPLACE FIELD_KEY WITH 1 IN MyView
SAVE_VIEW()

BROWSE NORMAL
SELECT Test
BROWSE NORMAL

CLOSE ALL
RETURN


PROCEDURE SAVE_VIEW()
LOCAL nRecno

nRecno = GETNEXTMODIFIED(0, "MyView")
BEGIN TRANSACTION
GOTO (nRecno) IN MyView
IF (nRecno != 0)
REFRESH(1, 0, "MyView")
CURVAL("FIELD_DATA", "Test")
ENDIF
= TABLEUPDATE(0, .F., "MyView")
= TABLEUPDATE(0, .F., "Test")
nRecNo = GETNEXTMODIFIED(nRecNo,"MyView")
END TRANSACTION
ENDPROC




"Benno" wrote:

> Dear all,
>
> The code beneath generates an error in VFP9. In VFP8 it runs fine.
>
> The purpose of the original code is to store data from a view into the
> database. The sample code doesn't really make sense anymore. We
> stripped the code down to its bare minimum. It's just a way to show
> the error.
>
> We don't think this code is illegal. So, is there a bug in VFP9?
>
> Regards,
>
> Roel, Bas and Benno.
>
>
>
> *=========== BEGIN CODE ============================
>
> CREATE DATABASE database
> OPEN DATABASE database
>
> CREATE TABLE test (FIELD_KEY I, FIELD_DATA I)
> INSERT INTO TEST (FIELD_KEY, FIELD_DATA) VALUES (0, 0)
>
> CREATE SQL VIEW MYVIEW AS SELECT * FROM test
> USE MYVIEW IN 1
>
> CURSORSETPROP("buffering", 5, 1)
> CURSORSETPROP("keyfieldlist", "FIELD_KEY", 1)
> CURSORSETPROP("UpdatableFieldList", "FIELD_KEY, FIELD_DATA", 1)
>
> REPLACE FIELD_DATA WITH 1 IN 1
> SAVE_VIEW()
>
> APPEND BLANK IN 1
> REPLACE FIELD_KEY WITH 1 IN 1
> SAVE_VIEW()
>
> PROCEDURE SAVE_VIEW()
> LOCAL nRecno
>
> nRecno = GETNEXTMODIFIED(0, 1)
> BEGIN TRANSACTION
> GOTO (nRecno) IN 1
> IF (nRecno > 0)
> REFRESH(1, 0, 1)
> CURVAL("FIELD_DATA", 1)
> ENDIF
> TABLEUPDATE(0, .F., 1)
> END TRANSACTION
> ENDPROC
>

Re: Transaction problem in VFP9 by Anders

Anders
Mon Feb 14 20:54:00 CST 2005

You don't need the line = TABLEUPDATE(0, .F., "Test"), do you?
-Anders


"Mark" <Mark@discussions.microsoft.com> wrote in message
news:0A33CA9F-BE67-43C8-B06D-CCF8018D9311@microsoft.com...
> Hi Benno,
> Next Time, you might want to read more carefully your helpfiles.
> I have changed your code in order to work - see below.
>
> hth
> Mark
>
> SET MULTILOCKS ON
> CREATE DATABASE database
> OPEN DATABASE database
>
> CREATE TABLE test (FIELD_KEY I, FIELD_DATA I)
> INSERT INTO TEST (FIELD_KEY, FIELD_DATA) VALUES (0, 0)
> CURSORSETPROP("buffering", 3, "Test")
>
> CREATE SQL VIEW MYVIEW AS SELECT * FROM test
> USE MYVIEW IN 0
> SELECT MyView
>
> CURSORSETPROP("buffering", 5, "MyView")
> CURSORSETPROP("keyfieldlist", "FIELD_KEY", "MyView")
> CURSORSETPROP("UpdatableFieldList", "FIELD_KEY, FIELD_DATA", "MyView")
> CURSORSETPROP("Tables","Test")
> CURSORSETPROP("SendUpdates",.T.)
>
> REPLACE FIELD_DATA WITH 1 IN MyView
> SAVE_VIEW()
>
> APPEND BLANK IN MyView
> REPLACE FIELD_KEY WITH 1 IN MyView
> SAVE_VIEW()
>
> BROWSE NORMAL
> SELECT Test
> BROWSE NORMAL
>
> CLOSE ALL
> RETURN
>
>
> PROCEDURE SAVE_VIEW()
> LOCAL nRecno
>
> nRecno = GETNEXTMODIFIED(0, "MyView")
> BEGIN TRANSACTION
> GOTO (nRecno) IN MyView
> IF (nRecno != 0)
> REFRESH(1, 0, "MyView")
> CURVAL("FIELD_DATA", "Test")
> ENDIF
> = TABLEUPDATE(0, .F., "MyView")
> = TABLEUPDATE(0, .F., "Test")
> nRecNo = GETNEXTMODIFIED(nRecNo,"MyView")
> END TRANSACTION
> ENDPROC
>
>
>
>
> "Benno" wrote:
>
> > Dear all,
> >
> > The code beneath generates an error in VFP9. In VFP8 it runs fine.
> >
> > The purpose of the original code is to store data from a view into the
> > database. The sample code doesn't really make sense anymore. We
> > stripped the code down to its bare minimum. It's just a way to show
> > the error.
> >
> > We don't think this code is illegal. So, is there a bug in VFP9?
> >
> > Regards,
> >
> > Roel, Bas and Benno.
> >
> >
> >
> > *=========== BEGIN CODE ============================
> >
> > CREATE DATABASE database
> > OPEN DATABASE database
> >
> > CREATE TABLE test (FIELD_KEY I, FIELD_DATA I)
> > INSERT INTO TEST (FIELD_KEY, FIELD_DATA) VALUES (0, 0)
> >
> > CREATE SQL VIEW MYVIEW AS SELECT * FROM test
> > USE MYVIEW IN 1
> >
> > CURSORSETPROP("buffering", 5, 1)
> > CURSORSETPROP("keyfieldlist", "FIELD_KEY", 1)
> > CURSORSETPROP("UpdatableFieldList", "FIELD_KEY, FIELD_DATA", 1)
> >
> > REPLACE FIELD_DATA WITH 1 IN 1
> > SAVE_VIEW()
> >
> > APPEND BLANK IN 1
> > REPLACE FIELD_KEY WITH 1 IN 1
> > SAVE_VIEW()
> >
> > PROCEDURE SAVE_VIEW()
> > LOCAL nRecno
> >
> > nRecno = GETNEXTMODIFIED(0, 1)
> > BEGIN TRANSACTION
> > GOTO (nRecno) IN 1
> > IF (nRecno > 0)
> > REFRESH(1, 0, 1)
> > CURVAL("FIELD_DATA", 1)
> > ENDIF
> > TABLEUPDATE(0, .F., 1)
> > END TRANSACTION
> > ENDPROC
> >


Re: Transaction problem in VFP9 by b

b
Tue Feb 15 06:33:05 CST 2005

Hi Mark,

Thanks for your reply. Your code works fine. The problem is though,
that it can hardly be applied in our original code. Explaining these
reasons would be beyond the purpose of this post.

You implied that we did something illegal by mentioning to read the
helpfiles more carefully. Could you point that out more clearly
please?

We are aware that the code we posted does not save anything, nor does
it do anything usefull. We did not try. We simply wanted to show a
problem we suffer from, using as little code as possible.

Regards,
Benno.

RE: Transaction problem in VFP9 by Mark

Mark
Tue Feb 15 09:43:15 CST 2005

Hi Benno,
There are several issues.

CURVAL() returns field values directly from disk for a table or a remote
data source. You must not use CURVAL() to return data from a local view.

In your code TRANSACTION is not necessary as you don't provide any way of
confirming or infirming the process, e.g.

Begin TransAction
lGoon = .T.
nNextRecord = GetNextModified(0,YourAlias)
Do While nNextRecord > 0 and lGoOn = .T.
Goto nNextRecord
If Mod(nNextRecord,1001) = 0 && fancy check
lGoOn = .F.
Endif
nNextRecord = GetNextModified(nNextRecord)
Enddo
If lGoOn
End TransAction
=TableUpdate(1, .T., YourAlias)
Else
RollBack
=TableRevert(.T., YourAlias)
EndIf

In fact your code might be stripped to a few lines and still does the same -
see below

SET MULTILOCKS ON
CREATE DATABASE database
OPEN DATABASE database

CREATE TABLE test (FIELD_KEY I, FIELD_DATA I)
INSERT INTO TEST (FIELD_KEY, FIELD_DATA) VALUES (0, 0)

CREATE SQL VIEW MYVIEW AS SELECT * FROM test
USE MYVIEW IN 0
SELECT MyView

CURSORSETPROP("buffering", 5, "MyView")
CURSORSETPROP("keyfieldlist", "FIELD_KEY", "MyView")
CURSORSETPROP("UpdatableFieldList", "FIELD_KEY, FIELD_DATA", "MyView")
CURSORSETPROP("Tables","Test")
CURSORSETPROP("SendUpdates",.T.)

REPLACE FIELD_DATA WITH 1 IN MyView
SAVE_VIEW()

FOR i = 1 TO 5
APPEND BLANK IN MyView
REPLACE FIELD_KEY WITH i IN MyView
SAVE_VIEW()
ENDFOR

BROWSE NORMAL && the view
SELECT Test
BROWSE NORMAL && the table

CLOSE ALL
RETURN

PROCEDURE SAVE_VIEW()
LOCAL nRecno
nRecno = GETNEXTMODIFIED(0, "MyView")
GOTO (nRecno) IN MyView
= TABLEUPDATE(0, .F., "MyView")

ENDPROC

hth
Mark

"Benno" wrote:

> Dear all,
>
> The code beneath generates an error in VFP9. In VFP8 it runs fine.
>
> The purpose of the original code is to store data from a view into the
> database. The sample code doesn't really make sense anymore. We
> stripped the code down to its bare minimum. It's just a way to show
> the error.
>
> We don't think this code is illegal. So, is there a bug in VFP9?
>
> Regards,
>
> Roel, Bas and Benno.
>
>
>
> *=========== BEGIN CODE ============================
>
> CREATE DATABASE database
> OPEN DATABASE database
>
> CREATE TABLE test (FIELD_KEY I, FIELD_DATA I)
> INSERT INTO TEST (FIELD_KEY, FIELD_DATA) VALUES (0, 0)
>
> CREATE SQL VIEW MYVIEW AS SELECT * FROM test
> USE MYVIEW IN 1
>
> CURSORSETPROP("buffering", 5, 1)
> CURSORSETPROP("keyfieldlist", "FIELD_KEY", 1)
> CURSORSETPROP("UpdatableFieldList", "FIELD_KEY, FIELD_DATA", 1)
>
> REPLACE FIELD_DATA WITH 1 IN 1
> SAVE_VIEW()
>
> APPEND BLANK IN 1
> REPLACE FIELD_KEY WITH 1 IN 1
> SAVE_VIEW()
>
> PROCEDURE SAVE_VIEW()
> LOCAL nRecno
>
> nRecno = GETNEXTMODIFIED(0, 1)
> BEGIN TRANSACTION
> GOTO (nRecno) IN 1
> IF (nRecno > 0)
> REFRESH(1, 0, 1)
> CURVAL("FIELD_DATA", 1)
> ENDIF
> TABLEUPDATE(0, .F., 1)
> END TRANSACTION
> ENDPROC
>

Re: Transaction problem in VFP9 by b

b
Wed Feb 16 06:16:10 CST 2005

Hi Mark,

I have two comments regarding your last post.

1.
The VFP-helpfile of the CURVAL function is not all that clear:
"Returns field values directly from disk for a table or a remote data
source."

This could mean, as you assume, that CURVAL can only be issued on a
table or on a remote data source and not on a view. (In that case it
could probably not be used with a remote view as well. At least the
documentation does not mention it.)

This could also mean, as I assume, that CURVAL when used with a local
or remote view returns values respectivily of the table on disk or
from the remote data source.

I think my assumption is supported by the Note in the helpfile (note
that it does not say anything about local or remote):
"If you are working with a view in a multiuser environment, the values
returned by CURVAL() might not be up to date unless you call the
REFRESH() function first. Data returned by a view is buffered, and the
CURVAL() function reads values from the buffer. However, if other
users have changed data in the underlying tables for the view, the
buffered data is not updated until the REFRESH() function is called."

2.
You wrote the following line:
"In your code TRANSACTION is not necessary as you don't provide any
way of confirming or infirming the process"

We are aware that our code is not useful. I agree that the use of a
transaction is not necessary here. It doesn't do anything at all. It
neither is, and that is important, illegal. In our original code the
use of a transaction is necessary. We just stripped the code to
reproduce the error using as little code as possible.

regards,
Benno.

Re: Transaction problem in VFP9 by Mark

Mark
Wed Feb 16 08:23:12 CST 2005

Hi Benno,

1.
>This could also mean, as I assume, that CURVAL when used with a local
> or remote view returns values respectivily of the table on disk or
> from the remote data source.

You're right, but you still need to send the updates to your table - which
was not done in your code. You return values from a record number that does
not exist in your table. Hence the error.

Compare your code

CURSORSETPROP("buffering", 5, "MyView")
CURSORSETPROP("keyfieldlist", "FIELD_KEY", "MyView")
CURSORSETPROP("UpdatableFieldList", "FIELD_KEY, FIELD_DATA", "MyView")

to mine, especially consider the last two lines which send the data to the
table

CURSORSETPROP("buffering", 5, "MyView")
CURSORSETPROP("keyfieldlist", "FIELD_KEY", "MyView")
CURSORSETPROP("UpdatableFieldList", "FIELD_KEY, FIELD_DATA", "MyView")
CURSORSETPROP("Tables","Test")
CURSORSETPROP("SendUpdates",.T.)

And you should also specify your Alias() in CURVAL() - also wrong in your
code, as you pointed to the view.

your code
>CURVAL("FIELD_DATA", 1)

and mine
CURVAL("FIELD_DATA", "Test")

2.
The TRANSACTION process is considered a whole or nothing process. The way
you implemented TRANSACTION is dangerous because you updated one record! You
should not TableUpdate() or TableRevert() within a TRANSACTION, but provide a
way to confirm or infirm it and then, outside the process, do the updating or
reverting.

hth
Mark


"Benno" wrote:

> Hi Mark,
>
> I have two comments regarding your last post.
>
> 1.
> The VFP-helpfile of the CURVAL function is not all that clear:
> "Returns field values directly from disk for a table or a remote data
> source."
>
> This could mean, as you assume, that CURVAL can only be issued on a
> table or on a remote data source and not on a view. (In that case it
> could probably not be used with a remote view as well. At least the
> documentation does not mention it.)
>
> This could also mean, as I assume, that CURVAL when used with a local
> or remote view returns values respectivily of the table on disk or
> from the remote data source.
>
> I think my assumption is supported by the Note in the helpfile (note
> that it does not say anything about local or remote):
> "If you are working with a view in a multiuser environment, the values
> returned by CURVAL() might not be up to date unless you call the
> REFRESH() function first. Data returned by a view is buffered, and the
> CURVAL() function reads values from the buffer. However, if other
> users have changed data in the underlying tables for the view, the
> buffered data is not updated until the REFRESH() function is called."
>
> 2.
> You wrote the following line:
> "In your code TRANSACTION is not necessary as you don't provide any
> way of confirming or infirming the process"
>
> We are aware that our code is not useful. I agree that the use of a
> transaction is not necessary here. It doesn't do anything at all. It
> neither is, and that is important, illegal. In our original code the
> use of a transaction is necessary. We just stripped the code to
> reproduce the error using as little code as possible.
>
> regards,
> Benno.
>

Re: Transaction problem in VFP9 by b

b
Thu Feb 17 04:24:19 CST 2005

> You're right, but you still need to send the updates to your table - which
> was not done in your code. You return values from a record number that does
> not exist in your table. Hence the error.
No, I do not. There is a check if GETNEXTMODIFIED returns a value
greater than zero.

> to mine, especially consider the last two lines which send the data to the
> table
We are aware that without those two lines you added, the code is
useless. But without those lines the code is still legal.

> And you should also specify your Alias() in CURVAL() - also wrong in your
> code, as you pointed to the view.
CURVAL can handle an alias as well as a workarea. Our code points to a
view, but (as we discussed above) that is also legal.

> 2.
> The TRANSACTION process is considered a whole or nothing process. The way
> you implemented TRANSACTION is dangerous because you updated one record! You
> should not TableUpdate() or TableRevert() within a TRANSACTION, but provide a
> way to confirm or infirm it and then, outside the process, do the updating or
> reverting.
In the VFP helpfiles (item BEGIN TRANSACTION) there is an example of a
TABLEUPDATE statement in a transaction block.

Re: Transaction problem in VFP9 by Mark

Mark
Thu Feb 17 05:25:06 CST 2005

Hi Benno,

> No, I do not. There is a check if GETNEXTMODIFIED returns a value
> greater than zero.
Of course does GETNEXTMODIFIED() return a non-zero number because your code
positions the record pointer at the NEXT MODIFIED record in your VIEW, not in
your TABLE and as your VIEW is buffered, you're only updating your VIEW.
Therefore you still have to send the updates to the table before you may use
CURVAL().

> We are aware that without those two lines you added, the code is
> useless. But without those lines the code is still legal.
You're right, but the code does not do anything. But you expect it to update
your TABLE, which is not the case.

> CURVAL can handle an alias as well as a workarea. Our code points to a
> view, but (as we discussed above) that is also legal.
First sentence ok. Second WRONG - CURVAL() ALWAYS return data from the table
or the remote data source!

> In the VFP helpfiles (item BEGIN TRANSACTION) there is an example of a
> TABLEUPDATE statement in a transaction block.
You're right, but it is a bad example and it is misleading you. Please check
"Hacker's Guide to Visual Foxpro" for a better understanding of the
TRANSACTION process.

hth
Mark

"Benno" wrote:

> > You're right, but you still need to send the updates to your table - which
> > was not done in your code. You return values from a record number that does
> > not exist in your table. Hence the error.
> No, I do not. There is a check if GETNEXTMODIFIED returns a value
> greater than zero.
>
> > to mine, especially consider the last two lines which send the data to the
> > table
> We are aware that without those two lines you added, the code is
> useless. But without those lines the code is still legal.
>
> > And you should also specify your Alias() in CURVAL() - also wrong in your
> > code, as you pointed to the view.
> CURVAL can handle an alias as well as a workarea. Our code points to a
> view, but (as we discussed above) that is also legal.
>
> > 2.
> > The TRANSACTION process is considered a whole or nothing process. The way
> > you implemented TRANSACTION is dangerous because you updated one record! You
> > should not TableUpdate() or TableRevert() within a TRANSACTION, but provide a
> > way to confirm or infirm it and then, outside the process, do the updating or
> > reverting.
> In the VFP helpfiles (item BEGIN TRANSACTION) there is an example of a
> TABLEUPDATE statement in a transaction block.
>

Re: Transaction problem in VFP9 by Mark

Mark
Thu Feb 17 09:33:08 CST 2005

Hi Benno,
> > CURVAL can handle an alias as well as a workarea. Our code points to a
> > view, but (as we discussed above) that is also legal.
> First sentence ok. Second WRONG - CURVAL() ALWAYS return data from the table or the remote data source!

I apologize, you're right with your second sentence too - CURVAL() is able
to return data from a view. But (from the helpfile):

If you are working with a view in a multiuser environment, the values
returned by
CURVAL() might not be up to date unless you call the REFRESH() function
first. Data returned by a view is buffered, and the CURVAL() function reads
values from the buffer. However, if other users have changed data in the
underlying tables for the view, the buffered data is not updated until the
REFRESH() function is called.

ImO it's always wise to send the updates to the underlying table!

Now to GETNEXTMODIFIED().
Your code checks if a record was changed: IF (nRecno > 0)
If a NEW record is added, and that's what you're doing, GETNEXTMODIFIED()
returns a NEGATIVE Number, so your code should be IF(nRecno != 0).
Unfortunately this is NOT documented in the helpfile, but as I said you might
want to consider "Hacker's Guide to Visual Foxpro"


Mark

"Mark" wrote:

> Hi Benno,
>
> > No, I do not. There is a check if GETNEXTMODIFIED returns a value
> > greater than zero.
> Of course does GETNEXTMODIFIED() return a non-zero number because your code
> positions the record pointer at the NEXT MODIFIED record in your VIEW, not in
> your TABLE and as your VIEW is buffered, you're only updating your VIEW.
> Therefore you still have to send the updates to the table before you may use
> CURVAL().
>
> > We are aware that without those two lines you added, the code is
> > useless. But without those lines the code is still legal.
> You're right, but the code does not do anything. But you expect it to update
> your TABLE, which is not the case.
>
> > CURVAL can handle an alias as well as a workarea. Our code points to a
> > view, but (as we discussed above) that is also legal.
> First sentence ok. Second WRONG - CURVAL() ALWAYS return data from the table
> or the remote data source!
>
> > In the VFP helpfiles (item BEGIN TRANSACTION) there is an example of a
> > TABLEUPDATE statement in a transaction block.
> You're right, but it is a bad example and it is misleading you. Please check
> "Hacker's Guide to Visual Foxpro" for a better understanding of the
> TRANSACTION process.
>
> hth
> Mark
>
> "Benno" wrote:
>
> > > You're right, but you still need to send the updates to your table - which
> > > was not done in your code. You return values from a record number that does
> > > not exist in your table. Hence the error.
> > No, I do not. There is a check if GETNEXTMODIFIED returns a value
> > greater than zero.
> >
> > > to mine, especially consider the last two lines which send the data to the
> > > table
> > We are aware that without those two lines you added, the code is
> > useless. But without those lines the code is still legal.
> >
> > > And you should also specify your Alias() in CURVAL() - also wrong in your
> > > code, as you pointed to the view.
> > CURVAL can handle an alias as well as a workarea. Our code points to a
> > view, but (as we discussed above) that is also legal.
> >
> > > 2.
> > > The TRANSACTION process is considered a whole or nothing process. The way
> > > you implemented TRANSACTION is dangerous because you updated one record! You
> > > should not TableUpdate() or TableRevert() within a TRANSACTION, but provide a
> > > way to confirm or infirm it and then, outside the process, do the updating or
> > > reverting.
> > In the VFP helpfiles (item BEGIN TRANSACTION) there is an example of a
> > TABLEUPDATE statement in a transaction block.
> >

Re: Transaction problem in VFP9 by Mark

Mark
Fri Feb 18 04:31:02 CST 2005

Hi Benno,
After some tests and a carefull reading of the TRANSACTION topic in
"Hacker's Guide to Visual FoxPro", I guess that CURVAL(), applied to return
data from a VIEW is not legal inside a TRANSACTION process.

From the Hacker's:
"... Updating is normally a two-step process. The user updates the buffers
by making changes. Then calls to TableUpdate() copy the changes from the
buffers to the actual tables. When you use transactions, you add another
layer to that. Tableupdate() copies the changes from buffers to another set
of buffers (call them "transaction buffers") and END TRANSACTION copies from
those buffers to the actual tables. ..."

As CURVAL() contains the data sitting in the buffers for views, and
considering the above, my guess is that CURVAL("MyField","MyView") does not
know from which buffers it should return the data - hence the error(s).

By the way I tested the code in VFP6 and VFP9 - there were no differences.

hth

Mark

"Mark" wrote:

> Hi Benno,
> > > CURVAL can handle an alias as well as a workarea. Our code points to a
> > > view, but (as we discussed above) that is also legal.
> > First sentence ok. Second WRONG - CURVAL() ALWAYS return data from the table or the remote data source!
>
> I apologize, you're right with your second sentence too - CURVAL() is able
> to return data from a view. But (from the helpfile):
>
> If you are working with a view in a multiuser environment, the values
> returned by
> CURVAL() might not be up to date unless you call the REFRESH() function
> first. Data returned by a view is buffered, and the CURVAL() function reads
> values from the buffer. However, if other users have changed data in the
> underlying tables for the view, the buffered data is not updated until the
> REFRESH() function is called.
>
> ImO it's always wise to send the updates to the underlying table!
>
> Now to GETNEXTMODIFIED().
> Your code checks if a record was changed: IF (nRecno > 0)
> If a NEW record is added, and that's what you're doing, GETNEXTMODIFIED()
> returns a NEGATIVE Number, so your code should be IF(nRecno != 0).
> Unfortunately this is NOT documented in the helpfile, but as I said you might
> want to consider "Hacker's Guide to Visual Foxpro"
>
>
> Mark
>
> "Mark" wrote:
>
> > Hi Benno,
> >
> > > No, I do not. There is a check if GETNEXTMODIFIED returns a value
> > > greater than zero.
> > Of course does GETNEXTMODIFIED() return a non-zero number because your code
> > positions the record pointer at the NEXT MODIFIED record in your VIEW, not in
> > your TABLE and as your VIEW is buffered, you're only updating your VIEW.
> > Therefore you still have to send the updates to the table before you may use
> > CURVAL().
> >
> > > We are aware that without those two lines you added, the code is
> > > useless. But without those lines the code is still legal.
> > You're right, but the code does not do anything. But you expect it to update
> > your TABLE, which is not the case.
> >
> > > CURVAL can handle an alias as well as a workarea. Our code points to a
> > > view, but (as we discussed above) that is also legal.
> > First sentence ok. Second WRONG - CURVAL() ALWAYS return data from the table
> > or the remote data source!
> >
> > > In the VFP helpfiles (item BEGIN TRANSACTION) there is an example of a
> > > TABLEUPDATE statement in a transaction block.
> > You're right, but it is a bad example and it is misleading you. Please check
> > "Hacker's Guide to Visual Foxpro" for a better understanding of the
> > TRANSACTION process.
> >
> > hth
> > Mark
> >
> > "Benno" wrote:
> >
> > > > You're right, but you still need to send the updates to your table - which
> > > > was not done in your code. You return values from a record number that does
> > > > not exist in your table. Hence the error.
> > > No, I do not. There is a check if GETNEXTMODIFIED returns a value
> > > greater than zero.
> > >
> > > > to mine, especially consider the last two lines which send the data to the
> > > > table
> > > We are aware that without those two lines you added, the code is
> > > useless. But without those lines the code is still legal.
> > >
> > > > And you should also specify your Alias() in CURVAL() - also wrong in your
> > > > code, as you pointed to the view.
> > > CURVAL can handle an alias as well as a workarea. Our code points to a
> > > view, but (as we discussed above) that is also legal.
> > >
> > > > 2.
> > > > The TRANSACTION process is considered a whole or nothing process. The way
> > > > you implemented TRANSACTION is dangerous because you updated one record! You
> > > > should not TableUpdate() or TableRevert() within a TRANSACTION, but provide a
> > > > way to confirm or infirm it and then, outside the process, do the updating or
> > > > reverting.
> > > In the VFP helpfiles (item BEGIN TRANSACTION) there is an example of a
> > > TABLEUPDATE statement in a transaction block.
> > >