PDox Survival Guide
PDox Survival Guide
Introduction
Professional and Enterprise versions of C++Builder and Delphi come with the ability to create, modify and manipulate Paradox, Xbase (DBase and !"C## database tables$ %he purpose of this paper is to discuss Paradox tables and provide the information necessary to create robust applications usin& this table format$ %he information here &oes into as much detail as possible$ %he &oal is to provide the reader with all the information needed to understand why thin&s are the way they are with Paradox tables$ #n some cases its more information than you probably want or need$ 'hat(s written here is the result of a number of years of personal experience with Paradox tables, the experiences and observations of customers of our Paradox %able )epair Component "et (see www$o*a$com+tu$htm , and various articles from ma&a,ines, the Borland and Corel websites$ !t the end of this paper you will find an extensive biblio&raphy of the sources$
Key Points
-ere are some .ey points to .eep in mind$
Paradox !s "ast
Because the Paradox scheme is not client+server record access and manipulation is extremely fast$ #n cases where the application and the tables are on the same system performance is &enerally orders of ma&nitude faster than the client+server case$ %his can even be the case when the application is accessin& tables over a networ. but here other factors come into play, li.e networ. traffic, database si,e, the number of people sharin& the tables, and table hit fre0uency$$ #n fact, because of Paradox(s extremely rapid access it(s used internally by the 1C2 to store and mana&e all cached updates$
Paradox tables provide a &ood platform wor.&roup (peer to peer applications where the number of concurrent users is expected to be few (less than 3* $ %ables can be stored on any machine in the wor.&roup and shared by all$ %he data can then be periodically synchroni,ed with a master Client+"erver database$
!t(s eas*
Paradox tables have none of the confi&uration issues associated with client+server databases$ 4ou can start desi&nin& and usin& table in the Database Des.top immediately after installin& Delphi of C++Builder$
Paradox Tables $orrupt easil*4es its true, in fact, this aspect of Paradox tables is the focus of much of this paper$ )ead on$
Some History
%his section is especially important if you have le&acy Paradox !pplications$
Table .evels
%he default table type created usin& the Database Des.top and the BDE (Borland Database En&ine is a Paradox 8$? althou&h the default can be chan&ed usin& the BDE administrator to Paradox table level @, 8, : or ;$ (=n the confi&uration tab navi&ate to Drivers A Bative A P!)!D=X and chan&e the 2E1E2 field $
%he table level is important because each ma6or release of Paradox implemented improvements to table structures$ %hat is, table level determines the features you have available -ere(s what you need to .now on thisC D !ll Paradox table levels from 3$? throu&h @$: are compatible with each other$ D 2evel 8$? added the new Binary 2ar&e =b6ect, (B2=bs data type as well as new types of "econdary #ndices$ 2evel 8$? supports two types of B2=b fields (Eemo and Binary $ !ttempts to read, write or manipulate level 8 or &reater tables with applications that only read lower level tables will return an error that the table is password protected$ D Paradox :$? added several new data types includin&C 2on& #nte&er, %ime, %ime"tamp, 2o&ical, !utoincrement, BCD, and Bytes$ D Paradox ;$? added a descendin& secondary index !ny table created or modified to include any of these newer features will be automatically advanced by the BDE to the appropriate table level$ %he BDE can read, write, and create Paradox table levels that are compatible with levels 3$? throu&h Paradox ;$?$ "o, for example, the BDE (or Database Des.top can read and write a level 3$? Paradox table but if the Database des.top is used to )estructure the table so one of the indexes is descendin& then the table structure is automatically updated to 2evel ; and the table will no lon&er be accessible by level one only applications$ Bote that the BDE will not chan&e the table level when only readin& or writin& data$ %he table level is only chan&ed when a )estructure is performed on the table$
Beware (TI-239B)
=ld applications that use the Paradox En&ine may have problems on systems &reater than 87< CPHs$ %#*@9B &ives this warnin&C %he Paradox En&ine has B=% been certified on the followin& chipsetsI 3$ #ntel Pentium (any speed *$ Cyrex @$ !ED %he Paradox en&ine relies on timin& for some operations$ %he speed of some CPHs can cause file loc. contentions in multi/user environments$ Youve been warned. !ctually, it(s really to bad, since the Paradox En&ine could have been a really nice lite replacement to the BDE for those 6ust wantin& Paradox functionality$
Alpha Fields
!lpha >ields are up to *:: characters lon& and consist of letters, numbers, special symbols li.e J, K, L, or M and other printable !"C## characters$ %hese show up in the DB Des.top as symbol !$ !nd map to the %"trin&>ield type in the 1C2$
Nu ber Fields
=nly numbers$ Bumber fields can hold positive or ne&ative values$ %he ran&e of values possible for a number field is from /3?@?; to 3?@?7 with 3: si&nificant di&its$ Hse number fields when you plan to perform calculations on the values in the fields$ Bumber fields are best used when you want to perform calculations on the values in the field$ #t is a &ood idea to use an alpha field rather than a number field for phone numbers or ,ip codes$ #n an alpha field, you can include parentheses and hyphens$ %his is the B field type in the DB Des.top and maps to the %>loat>ield in the 1C2$
!one" Fields
%hese are only numbers with positive or ne&ative values$ But by default, money fields are formatted to display decimal places and a money symbol$ )e&ardless of the number of decimal places displayed, the BDE reco&ni,es up to six decimal places when performin& internal calculations on money fields$ %his is the N symbol in the DB Des.top and maps to the %Currency>ield in the 1C2$
#hor$ Fields
%hese are whole numbers in the ran&e /@*,;<; to @*,;<;$ "hort fields re0uire less dis. stora&e than ordinary number fields$ %he " symbol in the DB Des.top and %"mall#nt>ield in the 1C2$
%on&In$e&er Fields
! @*/bit si&ned inte&er that contain whole numbers (nonfractional with complete accuracy in the ran&e /*38;87@<87 to *38;87@<8; (plus or minus * to the @3st $ 2on& inte&er fields re0uire more space to store than short fields$ %his is symbol # in the DB Des.top and maps into the %#nte&er>ield type in the 1C2$
B'( Fields
%his is numeric data in a BCD (Binary Coded Decimal format$ Hse BCD fields when you want to perform calculations with a hi&her level of precision than that available with the use of other numeric fields$ %he BDE uses the Currency type to wor. with data from BCD fields, and limits the precision of the BCD values it can support to 8 decimal places and *? si&nificant di&its$ Calculations on BCD fields are not performed as 0uic.ly as those on other numeric fields$ %he BCD field type is provided primarily for compatibility with other database types that use BCD data$ %he BCD encodin& scheme will tal. use ? to @* bytes of data dependin& on the number of di&its$ %his is the L symbol in the DB Des.top and maps to the %BCD>ield type in the 1C2$
(a$e Fields
!ny valid date from Oanuary 3, 9999 BC to December @3, 9999 !D$ %he BDE correctly handles leap years and leap centuries and chec.s all dates for validity$ %he BDE treats all BC years as leap years$ %he D symbol in the DB Des.top and %Date>ield in the 1C2$
Ti e Fields
%imes of day, stored in milliseconds since midni&ht, and are limited to *8 hours$ %his is the % symbol in the DB Des.top and maps to the %%ime>ield type in the 1C2$
Ti e#$a pFields
Contains both the time and date values$ )ules for this field type are the same as those for date fields and time fields$ #nternally the data is stored as a Double with the date encoded in the data to the left for the decimal and the time
encoded in the data to the ri&ht of the decimal$ %he P symbol in the DB Des.top and the %Date%me>ield in the 1C2$
!e o Fields
Hse memo fields for text strin&s that are too lon& to store in an alpha field$ Eemo fields can be virtually any len&th$ Eemo fields are B2=bs and you should read the section on B2=bs that follows$ Eemo fields can contain letters, numbers, special symbols (such as J, K, L, and M , or any other printable !"C## character (except null $ 4ou can enter line brea.s, tabs and other print control characters in memo fields$ Eemo fields use the symbol E in the DB Des.top and are the %ype %Eemo>ield in the 1C2$
)raphi* Fields
Paradox &raphic fields contain pictures$ Qraphic fields are B2=b fields (see below $ #ts possible to specify a field si,e for Qraphic fields but do not$ %he si,e should be ? so the &raphic data is not stored in the table, but in the separate EB file$ "ymbol Q in the DB Des.top and %Qraphic>ield in the 1C2$
+%, Fields
%he =2E field type is used to store different .inds of data, such as ima&es, sound, documents, and so on in the Paradox application$ %his is also a B2=b type field$ #t has no e0uivalent field type in the 1C2 and the Database Des.top does not support =2E data$ %his is the = field type in the DB Des.top and is not supported in the 1C2$
%o&i*al Fields
Paradox lo&ical fields contain values representin& true or false (yes or no $ By default, valid entries include R%rueR and R>alseR (case is not important $ "ymbol 2 in the DB Des.top and %Boolean>ield field type in the 1C2$
Binar" Fields
%hese are yet another type of B2=b field (see below $ =nly advanced users who need to wor. with custom data that the BDE cannot directly interpret should use binary fields$ %he BDE cannot display or interpret binary fields directly$ ! common use of a binary field is to store sound information$ Do not specify a si,e when creatin& a Binary field since they are stored in a separate file (the $EB file , not in the table ($DB file $ %his is symbol B in the DB Des.top$ %he advanced user usin& this field type would create a %Blob>ield descendent and extend the 1C2 for her specific needs$
B"$es Fields
Bytes fields should be used only by advanced users who need to wor. with data that Database Des.top cannot interpret$ ! common use of a bytes field is to store bar codes or ma&netic strips$Hnli.e binary fields, bytes fields are stored in the Paradox table (rather than in the $EB file , allowin& for faster access$ %he si,e of this field must be specified when the table is created and is limited to *:: bytes$ %his is symbol 4 in the DB Des.top$ %his maps to the %Bytes>ield in the 1C2$ #t(s up to the pro&rammer to ma.e sense of this unformatted data$
$4Qn
(B File #$ru*$ure
%he DB file is the central file of a Paradox table$ #t contains most of the data (except B2=b data which is in the EB file as well as critical header information$
89/:?h 'e don(t recommend directly manipulatin& any of these values$ %hey are here if illustration purposes only$ #mproper exits and hardware errors can cause the header to &et trashed when written (or fail to be written to dis.$
Bul&e V ! bloc. is inserted in only one strand of the chain$ %here are two variations, a bul&e can &o forwards or bac.wards$ '"*le V ! bloc. points to itself or a bloc. earlier in the chain$ (ead end V %he chain suddenly ends, leavin& the followin& bloc. stranded$ Invalid end V ! bloc. points completely out of the file havin& the same effect as Dead end$ %o correctly insert or delete a bloc., the BDE has to chan&e lin.s in three bloc.s$ !ny interruption in this lin. update process will corrupt the table$ %his .ind of corruption is amon& the most fre0uent due to improper exits, or hardware failures (see -ow %ables Qet Dama&ed below $
Locking Protocols
-istorically there have been two different Paradox loc.in& protocolsI the protocol introduced with Paradox *$? and the protocol introduced with Paradox 8$?$ %hese two protocols are not compatible$ %he loc.in& protocol has no bearin& on which type of table a pro&ram can wor. with$ %hat is, the loc.in& protocol is not tied to the table structure in any way$ "o, we will only focus on the 8$? loc.in& protocol since it(s the one the BDE uses$ %his section and the followin& section Paradox on the Betwro. contain purposeful repetition in the hope of ma.in& the concepts clearer$
Dire$tor* .o$'s
%he BDE places a loc.in& file, PD=XH")"$2CW, in each directory where tables are accessed$ %his loc.in& file re&ulates concurrent access to files in the directory$ %he loc. file references PD=XH")"$BE%, so every user must map to the data directory the same way$ #t also places an exclusive P!)!D=X$2CW file in the directory as well$ #t does this to prevent versions of Paradox or the Paradox En&ine usin& the older loc.in& system from inadvertently accessin& tables$
Wor'in%/Shareable Dire$tories
'hen the BDE needs to access Paradox tables in a directory, it places both a R"hareableR PD=XH")"$2CW file and an RExclusiveR P!)!D=X$2CW file in that directory$ %his desi&nation means that other BDE users can access tables in that directory$ %he exclusive P!)!D=X$2CW file is placed in this directory to .eep the older, incompatible loc.in& protocol from puttin& data at ris.$ #n Paradox spea., this is .nown as a R'or.in&R directory$ #n the 1C2 the wor.in& directory is specified in the %Database$Directory property$
Private/&x$lusive Dire$tories
%he BDE also needs a directory to store temporary files, such as the !nswer table from a 0uery$ 'hen the BDE starts, it also places both an RExclusiveR PD=XH")"$2CW file and an RExclusiveR P!)!D=X$2CW files in a directory, desi&natin& that directory as the location for temporary files$ %his desi&nation means that other BDE users+applications cannot access tables in that directory$ %his is .nown as a RPrivateR directory$ #n the 1C2 the private directory can be specified by settin& the %"ession$PrivateDir property$
Table .o$'s
%he BDE places each table loc. in the directory loc.in& file (PD=XH")"$2CW $ %he older loc.in& protocol used separated table loc. files$ >or example, if three users are viewin& the CH"%=EE)$DB table and one user is restructurin& the =)DE)"$DB table, the PD=XH")"$2CW file will have a shareable loc. listed for each of those three users who are viewin& the CH"%=EE)$DB table, and an exclusive loc. on =)DE)"$DB for the user who is restructurin& that table$
Con$urren$*
#n a multi/user environment, the Paradox 8$? loc.in& protocol maintains concurrency (the simultaneous use of applications throu&h the PD=XH")"$BE% file$ !ll users who want to share Paradox tables must map to the same PD=XH")"$BE% file in the same way usin& the same path, but not necessarily the same drive letter$ %he BDE places a PD=XH")"$2CW and an exclusive P!)!D=X$2CW file in each directory where tables are bein& accessed preventin& applications usin& the older loc.in& protocol from accessin& files in the same directory$ Each user who wants to share tables in that directory must map that directory the same way usin& the same drive letter and path$ Paradox then places all of the loc.in& information for that table in the PD=XH")"$2CW file, reducin& the number of files needed$
application, networ., and tables$ >or our example we have a computer system named >ooEachine, which has a shared directory called >oo"hare with subdirectories >oo%ables, >ooExe and >ooBetwor. >ooEachine ("hared Directory >oo"hare A A/// (%ables Directory >oo%ables A/// (EXE Directory >ooExe A/// (Betwor. Directory >ooBetwor. %here are two different BDE environments that must also be consideredI 3 Hsin& only BDE @*Bit applications$ * Hsin& BDE @*Bit applications alon& with BDE 3<Bit applications$
!#proper Appli$ation &xit4 Badl* )ritten pro%ra#s4 and Po)er Suppl* Proble#s4
By far the chief cause of Paradox table corruption comes from the fact that Paradox caches information in volatile memory$ #mproperly closin& files such as due to loss of power (or brown out or restartin& a wor.station or the server without closin& files first, or pro&rammatically closin& the file in an ille&al way may all cause table corruption$ Paradox tables are not desi&ned to withstand such behavior$ Hse sur&e protectors or HP"s$ Hnfortunately in many cases the real culprit here is the end/user$ %he day comes to and end and the user 6ust shuts off the machine$ %his is a trainin& issue$ Bote that most Client "erver databases are desi&ned to recover from such conditions$
!#proper Setup
"pecifically, incorrectly settin& the 2=C!2 "-!)E property$ Eost commonly this occurs in Peer/to/Peer networ.in&$ #n this case the two different database en&ines are on two CPHs, even thou&h they may be the same version$ "ee the section Paradox on a Betwor. above for more information and proper setup$ !nother condition is when two different database en&ines execute on the same CPH concurrently and access data locally$ %his would be true when any combination of followin& is used concurrentlyI !n application(s that uses the Paradox En&ine, BDE 3< bit, BDE @* bit, Paradox for D="$ #n this case each en&ine must set 2=C!2 "-!)E to %)HE$ Bote that two applications usin& the sane BDE (for exampleI Delphi : and C++ Builder : concurrently are not a problem and 2=C!2 "-!)E does not need to be set to %)HEC #n this case, all loc.in& and cached data is in a central memory pool which all BDE applications have access to$ !lso, if two different database en&ines use data remotely, 2=C!2 "-!)E must be set to %)HE$ #ts possible to write code used in your application startup to chec. the settin& of local share$ 2oo. at the Dbi=penCf&#nfo2ist BDE !P# function call in the BDE help file for more information (bde@*$hlp $
Net)or' Proble#s
Error transmittin& data from the wor.station to the server can corrupt data$ Eost commonly, this occurs with bad networ. hardware (cable, card, hub, etc$ $ %his has been determined to be a problem even thou&h there were no other errors are detected in data transmission$ %o determine if this is the cause for your error, try eliminatin& one CPH at a time from usin& the data and see if the problem continues$
problems$ %hese bad 1XD(s will cause the errors RBlob has been modifiedR and+or R#ndex is out of date$R #f any one of the clients has a RbadR version of this device driver, the error can occur on any machine, not 6ust the machine with the bad driver$ %his error is most li.ely occurs in 3<Bit versions of the Borland Database En&ine, althou&h it still can occur in @*Bit versions$ %o fix the problem download and execute 1rdrupd$exe from support$microsoft$com+download+support+mslfiles+1rdrupd$exe$ %he followin& files are installed by 1rdrupd$exe in the Y'indowsY"ystem directoryC 1redir$vxd (ver 8$??$333<, 9+33+9;, 33I3<a, 3:<,;;@ bytes and 1netsup$vxd (ver 8$??$333*, :+@?+9;, 33I3*a, 3;,:9: bytes >or further information on the update of 1)ED#)$1XD, Please chec. the followin& Eicrosoft Developer Betwor. !rticlesI 53;8@;3 and 53<:8?@
Green Devi$es
Corel recommends that you disable all &reen (ener&y/savin& hardware and software$ =ften table corruption may occur when usin& &reen monitors, &reen cards and other &reen devices$
Write,Behind Ca$hin%
>or :indows 3.5 / ensure that "E!)%D)#1E or any other cachin& pro&ram does not perform write/behind cachin&$
>or :indows /or :or.&roups 3.51 V disable dis. write cachin& in the "4"%EE$#B# in the Z@7<Enh[ section and add an entry to disable @*/bit write/cachin& on all drives that have shared data on them, e& >orce2a,y=ffMCDE$ Eicrosoft Wnowled&eBase article 53?;<8: describes this option and article 53?73?9 emphasi,es that Z@7<Enh[ is the correct section, not Zvcache[ as mentioned in the )esource Wit documentation$ #f !H%=EXEC$B!% loads the "E!)%D)1$EXE pro&ram, ma.e sure the /X parameter is used to disable write/behind cachin& >or :indows 9; and 9< V >rom the control panel select the "ystem #con, than on the Performance tab clic. the >ile "ystem button and choose %roubleshootin&$ Chec. the option to FDisable write/behind cachin& for all drivesG$
?nverified 6oodoo
%he followin& points have been mentioned as bein& causes of table corruption but not been formally tested$
D 'indows 9: =nlyI Brin& up the networ. properties screen on all 'or.stations and enter the netBEH#
properties screen$ =n the advanced tab, ma.e sure that R"et this protocol to be the default protocolR is chec.ed$
D 'indows 9: =nlyI #f the previous su&&estion did not wor., try removin& the followin& protocols in order$
)emove one at a time and then re/test your problemI BE%B#=" support for #PX+"PX/compatible Protocol , %CP+#P , and #PX+"PX/compatible Protocol
D #f the problem disappears, attempt to add bac. in all protocols e1*ep$ for the last one that was ta.en out$
!&ain, ma.e sure netBEH#Us default protocol chec. box is chec.ed$
D 'indows B% =nly used as a 'or.stationI =n the Betwor. Bindin&s pa&e of the Betwor. Properties, set the
BetBEH# Protocol to be at the top of all services$ %he %CP+#P stac. is .nown for havin& alot of overhead that mi&ht cause timin& problems$ "ince B% will send re0uests bac. in the same protocol as it is sent, chan&in& the bindin&s on a B% machine used as a server will have no effect$
How to
!nother &ood place to call >lushBuffers would be in the !pplications$=n#dle event$ #n that case you would call the >lushBuffers for all modified tables in your application$
Win2 0 Appli$ations
#n Delphi 3, write a wmXEnd"ession messa&e handler for your main form and call -alt in it$ %his ensures the BDE closes down and hopefully flushes all its buffers$ !lso, ma.e sure "-!)E is loaded with the parameters su&&ested by Borland +>I8?9< +2I8?$
#ommon $rror
@ "et the sessionUs networ. directory to the BE% directory$ %a.e the followin& steps accordin& to the software you are usin&$
Sessio&'1etFileDir :( )*tractFilePat"(ParamStr(+)) , -1)T-$
8 #f 2=C!2 "-!)E is set to true and you are not sharin& tables between different applications at the same time, chan&e 2=C!2 "-!)E to false$ %his should correct the 2oc. >ile %oo 2ar&e error$
CSharin% 6iolationD
%his error is most commonly caused by a R2oc. >ile ContentionR$ ! loc. file contention occurs when user R!R, is accessin& one or more Paradox tables in a directory$ R!R is closin& the last table in the directory$ %he BDE detects that R!R is the last pro&ram accessin& the tables in the directory$ "ince R!R is the last user on the tables, the $2CW files are &oin& to be deleted$ !t this time, user RBR attempts to open a table in the same directory$ RBR opens the $2CW files to write an entry to it$ %his is when R!R tries to delete the $2CW files that RBR has 6ust now opened$ %his will cause a sharin& violation on the $2CW files$ %he share violation usually occurs on the last client to close the table$
%here are a few of solutions to this situation$ "olution 3 %he first solution is to override 'indows error routines and i&nore the error$ #n all test cases, then a sharin& violation occurs, the table is still opened or closed$ %o accomplish this, use the 'indows !P# "etErrorEode passin& the "EEX>!#2C)#%#C!2E))=)" constant$ 4ou would only need to do this before openin& and closin& a table and then chec. to see if the table has actually been open$
"olution * %he second solution is to .eep the 2CW files in the tableUs directories$ #f the BDE detects that more than one !pplication (or "ession is usin& the tables, it will not attempt to delete the $2CW files therefore solvin& the problem$ !ccomplish this by creatin& a RDummyR Paradox table in each table directory that the application uses$ ExampleI executable is in directory CIYEyPro&$ %his executable opens tables in two different directories / CIYEy%ables and DIY%emp%bl$ Create a RDummyR table with the Database Des.top, or any other Paradox table creation utility, in both the CIYEy%ables and DIY%emp%bl directories$ =nce the tables are created, create an application that opens each of the RDummyR pro&rams at startup$ 2eave this pro&ram runnin& at all times$ =ptimally, this executable is placed on a server machine, li.e 'indows B%, so whenever other applications are accessin& the data, the server also has the RDummyR tables open$ "olution @ 2eave at least one table durin& the entire applicationUs run$ =pen one table durin& application startup don(t close it until exit$ "olution 8 Hse the Dbi!c0Persist%able2oc. BDE !P# function to create a loc. on a table that does not exist$ "ee bde@*$hlp for details$ Be aware that each instance of the application must have a uni0ue, non/existent table name or an attempt to place a loc. in the directory will fail$ #f this method is used, an al&orithm must be used to &uarantee a uni0ue table names$ #f a user can only run one instance of the pro&ram at a time, the networ. user name can be used as a table name$ Addi$ion no$es %he sort of F2oc. >ile ContentionG problem does not seem to occur on B% wor.station machines$ %he application can be either 3< or @* bit$ "etErrorEode seems to wor. with both cases$ %he problem is more li.ely to occur if the networ. protocol is netBEH#$ #f possible use netB#=" or #PX+"PX$ Constant closin& and openin& of tables will cause this error more often$ %he error most commonly occurs on the close of the table, not the open$ #n this situation the closin& application tries to delete files that another application now has open$
7epair steps
%here are several steps involved in repairin& table corruption$ 3$ >eboo$ >irst try rebootin& your system(s and ma.e sure the corruption messa&e is real$ #t turns out that some corruption messa&es may be 6ust a misunderstandin& between volatile memory, dis. memory and the BDE$ #f after rebootin& the error is still manifest then ] &o on$ *$ 2repara$ion Before you be&in with repair utilities, you should always ma.e a bac.up of all files (corrupt or not $ #ts possible the repair utility could ma.e thin&s worse so ma.e sure you .eep an earliest version of the corrupt files around$ %his is especially important if you have to resort to step <$ 4ou will also need to have exclusive access to the files$ #f possible copy them to a local hard drive and disconnect from the networ.$ #f this is not possible, ma.e sure that no one else has access to the tables while you are wor.in& on then$
8$
#f the %H%#2@*$D22 is passed a table name and the messa&e FCannot open tableG then the dama&e is to serious for the D22 and you should continue on to step 8$$ >e ovin& inde1es Corruption can sometimes occur in the .eys, indexes or validity chec.s of a table$ %his sort of corruption is dealt with by deletin& these elements, and then recreatin& them usin& the Database Des.top(s restructure tool$ "tart up DB Des.top and select %ools A Htilities A #nfo "tructure and select the problem table$ 'rite down A%% of the structure information about indexes, validity chec.s etc$$ #f you &et an error messa&e FHnable to open tableG or FCorrupt index other than headerG, you will not be able to write down the information about the table structure$ 4ou can still continue with this sectionC however, you will need to .now what indexes and validity chec.s you have defined so that you can recreate them later$ 'rite down what fields are part of the primary .ey, the validity chec.s for each field (if any , what table loo.ups are defined, etc$ 4ou will need to recreate all of these entries in a moment$ Close DB Des.top and open 'indows Explorer and select the directory where the tables are located$ #n that directory, you(ll see a number of files with identical names, but with different extensions$ Delete any files that have the same name as the table in 0uestion, and have any of the followin& extensions PX, $X^^, $4^^, $%1, $>!E, or 1!2$ (o no$ delete the $DB or $EB filesC these contain your data and B2=b (memo fields$ =nce these files are deleted, you should be able to open and use your tables so restart DB Des.top and re/define all of you indexes, validity chec.s and referential inte&rity$ #f you still can(t open your files then &o on to step :$ )ecreate the primary .ey, validity chec.s, secondary indexes, etc$ by selectin& %ools A Htilities A )estructure, re/ enterin& the items you wrote down earlier and save$ 4our table should wor. correctly now$
:$ ,1por$ $o A#'II
%his method is the most thorou&h way of removin& corruption from a table$ %he data is completely separated from the structure of the table$ %he old table structure is discarded and re/entered$ %he data is then imported bac. into a new structure$B=%EI %his method will not wor. for Eemo, Qraphic, =2E or Binary fields$ ! discussion of the what(s needed to export a Paradox table to an !"C## file is beyond the scope of this paper$ %here are two articles on the sub6ect on the Borland web site$ %hese are %#79*D$%X%(!rticle #D 3:79* FHsin& the !"C## Driver with Comma/delimited >ilesG and also >!539<?C$%X%(!rticle #D 3<9<? FConvertin& !"C## files to Paradox %ablesG another really &ood article on the sub6ect by Dr$ Cary Oensen can be found on the Delphi Ea&a,ine web site at www$delphima&$com+features+3999+?<+di3999?<c6Xf+di3999?<c6Xf$asp $ Hsin& the same methods as above, ma.e a list of the field names, types and si,es, as well as the .eys, indices, validity chec.s, etc$ and export your table to F!"C## Delimited %extG format$ =nce you have verified that all of the records have exported correctly (open the text file in 'ordPad , you can delete the ori&inal table$ Bow create a new table with the ori&inal nane and re/import the !"C## table into the Paradox table$
iscellaneous F%&
! have a paradox table that uses a pass)ord 5o) do ! #a'e it so that the for# that uses the table $o#es up )ithout pro#ptin% the user for the pass)ord?
%he table componentUs !C%#1E property must be set to >!2"E (#f it is active before you have added the pasword, you will be prompted $ %hen, put this code in the handler for the formUs =nCreate eventI
Sessio&'AddPass2ord(-34 secret 5ass2ord-)$ Table1'Active :( Tr!e$
=nce you close the table, you can remove the password with )emovePassword(UEy secret passwordU , or you can remove all current passwords with )emove!llPasswords$ (BoteI %his is for Paradox tables only$
! have referential inte%rit* set on #* Paradox ho) do ! do a $as$adin% delete of #* $hild re$ords?
Paradox tables offer a )eferential #nte&rity feature$ %his feature prevents addin& records to a child table for which there is no matchin& record in the parent table$ #t will also cause the .ey field(s in the child table to be chan&ed when the correspondin& .ey field(s in the parent are chan&ed (commonly referred to as a cascadin& update $ %hese events occur automatically, re0uirin& no intervention by a Delphi or C++Builder application usin& these tables$ -owever, the Paradox )eferential #nte&rity feature will not accommodate cascadin& deletes$ %hat is, the 1C2 will not allow you to delete a record in the parent table while matchin& records exist in the child table$ %his would ma.e RorphansR of the child records, losin& referential inte&rity$ %he 1C2 raises an exception when an attempt is made to delete such a parent record$ %o effect a cascadin& delete re0uires that the deletion of the matchin& child records be deleted pro&rammatically // before the parent record is deleted$ #n a 1C2 application, this is done by interruptin& the process of deletin& the record in the parent table, deletin& the matchin& records in the child table (if there are any , and then continuin& with the deletion of the parent record$ ! record in a table is deleted by a call to the Delete method of the %%able component, which deletes the current record in the associated table$ #nterruptin& the this process to first perform some other operations is a matter creatin& a procedure associated with the BeforeDelete event of the %%able$ !ny commands in a BeforeDelete event procedure are executed before the call actually &oes out from the application to the BDE to physically remove the record from the table file$ %o handle the deletion of one or more child records, in a BeforeDelete event procedure the Delete method for the %%able representin& the child table is called in a loop$ %he loop is based on the condition of the record pointer in the table not bein& positioned at the end of the data set, as indicated by the Eof method of the %%able$ %his also accounts for there bein& no child records at all matchin& the parent record to be deletedI if there are no matchin& records, the record pointer will already be at the end of the data set, the loop condition will evaluate to >alse, and the Delete method in the loop never &ets executed$ -ere(s an example on =b6ect Pascal$
5roced!re TForm1'Table1#eforeDelete(DataSet: TDataset)$ be6i& 2it" Table7 do be6i& Disable8o&trols$ First$ 2"ile &ot )of do Delete$ )&able8o&trols$ e&d$ e&d$
#n the above example, the parent table is represented by the %%able component %able3 and the child by %able*$ %he DisableControls and EnableControls methods are used as a cosmetic measure to free,e any data/aware components that mi&ht be displayin& data from %able* while the records are bein& deleted$ %hese two methods ma.e the process visually appear smoother, but are only optional and not essential to this process$ %he Bext method need not be called within this loop$ %his is because the loop be&ins at the first record and, as each record is deleted, the record that previously followed the deleted record moves up in the data set, becomin& both the first and the current record$ %his example presumes that the parent and child tables are lin.ed with a Easter/Detail relationship, as is typical for tables for which such )eferntial #nte&rity is confi&ured$ 2in.in& the tables in this manner results in only those records in the child table that match the current record in the parent table bein& available$ !ll other records in the child table are made unavailable throu&h the Easter/Detail filterin&$ #f the tables are not so lin.ed, there are two additional considerations that must be accounted for when deletin& the child records$ %he first is that a call to the >irst method may or may not put the record pointer on a record that matches the current record in the parent table$ %his necessitates usin& a search method to manually move the record pointer to a matchin& record$ %he second consideration affects the condition for the loop$ Because records other than those matchin& the current record in the parent table will be accessible, the condition for the loop must chec. that each record is a matchin& record before attemptin& to delete it$ %his chec.in& is in addition to 0ueryin& the Eof method$ Because the records will be ordered by this .ey field (from a primary or secondary index , all of the matchin& records will be conti&uous$ %his leads to the &iven that, as soon as the first non/matchin& record is reached, it can be assumed that all matchin& records have been deleted$ %hus, the previous example would be modified toI
5roced!re TForm1'Table1#eforeDelete(DataSet: TDataset)$ be6i& 2it" Table7 do be6i& Disable8o&trols$ Fi&d9e4(:Table1'Fields:+;'AsStri&6;) 2"ile (Fields:+;'AsStri&6 ( Table1'Fields:+;'AsStri&6) a&d (&ot )of) do Delete$ )&able8o&trols$ e&d$ e&d$
#n the above, it is the first field in the parent table (%able3 upon which the )eferential #nte&rity is based, and the first field in the child table (%able* a&ainst which matchin& is 6ud&ed$
! a# atte#ptin% to add data to #* Paradox table but !F# %ettin% the &rror BTable is "ullB What is the $ause of this and ho) $an ! add #ore re$ords?
Paradox tables have a bloc. si,e which determines the maximum record si,e for a table and the tableUs maximum si,e$ By default tables have a bloc. si,e of * or 8W$ )e&ardless of the bloc. si,e, tables can have a maximum of <8W bloc.s$ %his means by default a table can &row to *:< EB$ 4ou can increase the bloc. si,e of a table in 3 of two ways$ )un BDE !dmin and chan&e the bloc. si,e for the Paradox driver to a revised number$ 2e&al bloc. si,es are 3?*8, *?87, 8?9<, 3<@78 and @*;<7$ #f your bloc. si,e is lar&er then 8?9< then you must also chan&e level to be at least :$ >inally, create a new table and batchmove your data from your old table to your new table #t is also possible to chan&e the bloc. si,e of an existin& Paradox table by callin& BDE !P# function dbiDo)estucture (see bde@*$hlp $ >or an example see www$borland$com+devsupport+bde+files+pxrest$,ip
S< : TStri&6<ist$ be6i& { )&s!re #D) is i&itialised % Sessio&'=5e&$ S< :( TStri&6<ist'8reate$ Sessio&'>et8o&fi6Params(-?S4stem?/&it-@--@S<)$ res!lt :( (-T.A)- ( S<'0al!es:-<=8A< SBA.)-;)$ S<'Free$ e&d$
Bote that Delphi 3 did not support the >et8o&fi6Params menthod so you will need to call the BDE !P# method DbiQet"ysConfi& to &et the local share value$
A$$essin% the PD/G?S7S N&T file on Novell drive ta'es H,0I se$onds )ith Windo)s 89 Client for Novell /$$urs )ith an* BD& $lient
Problem only occurs with Bovell client$ Eicrosoft is =W$ "o, the simplest solution is to switch to Betware client$ !lso, accordin& to Bovell the problem only occurs with 'indows 9: and 97$ 'indows B% are fine$ Bovell has a discussion of this problem on their web site$ #t may be found by &oin& to support$novell$com+search+.bXindex$htm, search on pdoxusrs$net, then select the document called Rslowness when launchin& Paradox on 'indows 9:R -ere is the solution this document statesI Cache writes M off Close Behind %ic.sM? >ile Cachin&M? 2oc. DelayM3 2oc. )etriesM3 )ead =nly CompatibilityM on %rue CommitM=n =pportunistic 2oc.in&Moff (with the older client
%o use this procedure specify the destination path of the 2CW file in the DirPath paramter$ =n return, both a PD=XH")"$2CW and Paradox$lc. file will be in the DirPath location$ !ll you need do is copy the resultin& PD=XH")"$2CW to the CD/)=E master ima&e$ (%he P!)!D=X$2CW file is only necessary when accessin& Paradox for D=" tables so you can delete it$
'e(erences
Borland Te$hni$al Arti$les ))) borland $o#
%#@@8* (Article ID: 15209 1iews on the Paradox corruption issue %#3:88@ (Article ID: 15443 !utoincrement value of Paradox table %#38@;D (Article ID: 16437 Paradox 2oc.in& Protocols %#99*D (Article ID: 15992 !utomatin& lo&on for Paradox tables %#*<:B (Article ID: 15265 "harin& 1iolation Error with Paradox %ables %#3@@@D (Article ID: 16333 Paradox %ables on CD/)=E >!5@;89B (Article ID: 18749 %ables lan&ua&e drive must be correct >!5@;9B (Article ID: 15379 !ccess to PD=XH")"$BE% slow %#*93@D (Article ID: 17913 Ea.in& sure chan&es survive a power failure %#7<*D (Article ID: 15862 Cascadin& Deletes w Pdox )eferential #nte&rity %#8*B (Article ID: 15042 Pac.in& Paradox table %#3*:<B (Article ID: 15256 )emovin& F2oc. file $ to $ lar&eG Error %#3:38@ (Article ID: 10318 Paradox %able full fix by chan&in& bloc. si,e %#<9B (!rticle #DI 3:?<9 Common Paradox Error Eessa&es %#*8;B (Article ID: 15247 BDE "etup for Peer to peer networ.s >!5@3@B (Article ID: 15313 Paradox >ile Extensions %#:B (Article ID: 15212 Paradox$BE% file explained %#*@9B (Article ID: 15212 %he Paradox En&ine %#*7?3C (Article ID: 17801 'ritin& a Buffer Dis.
/ther
www$itecu.$com+Delma&+Paradox$htm )eally &ood articles on the sub6ect from a really &ood (li.ely the best Delphi ma&a,ine$$ www$turbopower$com+newsletters+?;97+default$asp / Discussion of the 'indows 9: redirector problem and B% opportunistic loc.in&I msdn$microsoft$com / 5387@<; discusses the 'in9: redirector bu& www$daccess$com+"upport+#nte&ratin&XD>XwithXBet'are$htm / Discussion of Bovell settin&s to avoid data lossI support$novell$com+search+.bXindex$htm !rticle *93;??* describes a Bovell read cachin& problemC article *9338<3 describes potential data loss issues usin& 'indows 9: a&ainst a Bet'are @$33 serverI orionweb$lotus$com+sims+c7f<X:8<$htm / ccIEail technical paper 388*9@ discussin& various 'indows re&istry settin&s that need to be set correctly to avoid data lossI orionweb$lotus$com+sims+7a;<X:8<$htmccIEail technical paper 3@9;38 discussin& preferred Bet'are settin&s to avoid data lossC if you use Bet'are you should read this as it describes many preferred Bet'are confi&uration settin&s not discussed hereI