Question : Visual Fox Pro Error

I have an error that pops ups every now and then, and is not limited to one pc.  When I am packing a database in Fox Pro, it tells me that the database does not exist, and then deletes my database off the server.  Really has me puzzled?  Any help would be appriacated.

Answer : Visual Fox Pro Error

The principle syntax is SET RELATION TO expression INTO work area/alias name. This means you're setting a relation via the FIELD footprint into the TABLE tw_base. The source table of that relation is the currently selected alias, and from the code I see that is tw_base itself, so you're self referencing.

So your code does not exactly look correct, as said about the relation you setup there, looks wrong. There is no second alias from which the relation begins, at least you don't set it as the active alias.

If this is still shortened code, please make sure it's reflecting the essence correctly.


I wonder if the pack may be failing because of the relation being set.

If you delete records they are only marked deleted in dbfs, you will know this Still no SQL, APPEND FROM or whatever command reading a dbf in VFP will read and output these records, which are marked deleted, as long as SET("DELETED") is "ON".

If some other program still sees them in the dbf without packing, then that program is working in SET("DELETED")="OFF" mode, which would be a bad design.

The main pint is, taht PACK is meant to fail in concurrent and frequent use, if the concurrent pack comes in the moment the original file is gone and the temp file is not renamed back to the original one.

You could try and replace the pack with this code, which does act within the exact same file. It does also create a temp file for security (to be able to reconstruct data in case of a failure), but it will then not delete the original and rename the copy, but fill in the original after zapping it and delete the copy.

You may try myPack() instead of the native PACK.

Bye, Olaf.
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:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:
57:
58:
59:
60:
61:
62:
63:
64:
65:
66:
67:
68:
69:
70:
71:
72:
73:
74:
75:
76:
77:
78:
79:
80:
81:
* testing with three aliases: a cursor curTest and a table tabTest
Create Cursor curTest (cTest C(10))
Append Blank
Append Blank
Delete Next 1
myPack()

Create Table tabTest Free (cTest C(10))
Append Blank
Append Blank
Delete Next 1
myPack()

* an unpacked cursor as reference
Create Cursor curTest2 (cTest C(10))
Append Blank
Append Blank
Delete Next 1

Set Deleted off
Set
* take a look at the difference between curTest2 and the other two aliases.

* the core procedure to pack within the same dbf file:
Procedure myPack(tcAlias)

   Local llShared, lcTempDBC, lcTempDBF

   If Empty(tcAlias)
      tcAlias = Alias()
   EndIf

   If Not IsExclusive(tcAlias)
      llShared = .T.
      Try 
         Select (tcAlias)
         Use Dbf(tcAlias) Exclusive
      Catch
         *
      EndTry
   EndIf 

   If Not IsExclusive(tcAlias)   
      Return .F.
   EndIf 

   lcTempDBC = Addbs(GetEnv("TEMP"))+Sys(2015)+".dbc"
   lcTempDBF = ForceExt(lcTempDBC,"dbf")

   Create Database (lcTempDBC)
   
   Select (tcAlias)
   * during this copy data in lcTempDBF grows, 
   * tcAlias has all data in it in any moment
   Copy To (lcTempDBF) Database (lcTempDBC) For NOT Deleted(tcAlias)

   * at this point the data of tcAlias exists twice,
   * first still within tcAlias, second in lcTempDBF
   Zap In (tcAlias)
   * now data only exists in lcTempDBF
   * this has truncated the dbf, fpt and the cdx of tcAlias

   Select (tcAlias)
   * during this append data in the original tcAlias file grows again, 
   * lcTEmpDBF has all data in it in any moment
   Append From (lcTempDBF)

   * now the data again exists twice in lcTempDBF and tcAlias, without any deleted records,
   * cdx and fpt also is rebuilt from scratch.
   * so we can safely close and delete lcTempDBF and the lcTempDBC
   Set Database To (lcTempDBC)
   Close Database
   Delete Database (lcTempDBC) DeleteTables && delete

   If llShared
      Select (tcAlias)
      Use Dbf(tcAlias) Shared
   EndIf
   
   Return .T.
EndProc
Random Solutions  
 
programming4us programming4us