Solved

Change paradox field type at run time

Posted on 2002-04-22
15
883 Views
Last Modified: 2008-01-16
Hi all,

In a paradox table I have a field
Field Name     Type     Size
Info Content     A       250

I want to be able to change this permanently to a memo 100 ( and retain the same field name) in a  run time application. This update application will be separate to the database program.
Basically I am updating a clients database and just want him to press a button to make all the changes.

Data is currently being stored in this field and I don't want to lose the data.

Please any suggestions gratefully received
0
Comment
Question by:Vanessa
  • 6
  • 3
  • 2
  • +3
15 Comments
 
LVL 6

Expert Comment

by:DrDelphi
Comment Utility
I am almost positive that you won't be able to do this while the first application is accessing the table. What you *could* do, however is to close the first application, create another table with a unique name and the all the field information of the first table, with the exception of this of this one field of course which you'd make a memo (or blob as the case may be). Copy the first table to the second, drop the firt table and rename the second to the first's name. In psusedo code it would be sonething like this:

Close App1.(using Main.DB)

CreateTable Temp.DB (identitical to Main.DB table, except blob field)

Copy Main.DB to Temp.DB


Drop Main Table.


Rename Temp.DB -> Main.DB


Hope this helps.


Good luck!!



0
 
LVL 27

Expert Comment

by:kretzschmar
Comment Utility
from my paq

alpha->tmemo for paradox

so it goes

include in your uses clause the unit bde

and add this code to your unit

//paste from the url

type
 ChangeRec = packed record
   szName: DBINAME;
   iType: word;
   iSubType: word;
   iLength: word;
   iPrecision: byte;
 end;


procedure ChangeField(Table: TTable; Field: TField; Rec: ChangeRec);
var
 Props: CURProps;
 hDb: hDBIDb;
 TableDesc: CRTblDesc;
 pFields: pFLDDesc;
 pOp: pCROpType;
 B: byte;

begin
 // Initialize the pointers...
 pFields := nil; pOp := nil;
 // Make sure the table is open exclusively so we can get the db handle...
 if Table.Active = False then
   raise EDatabaseError.Create('Table must be opened to restructure');
 if Table.Exclusive = False then
   raise EDatabaseError.Create('Table must be opened exclusively to restructure');

 Check(DbiSetProp(hDBIObj(Table.Handle), curxltMODE, integer(xltNONE)));
 // Get the table properties to determine table type...
 Check(DbiGetCursorProps(Table.Handle, Props));
 // Make sure the table is either Paradox or dBASE...
 if (Props.szTableType <> szPARADOX) and (Props.szTableType <> szDBASE) then
   raise EDatabaseError.Create('Field altering can only occur on Paradox' +
               ' or dBASE tables');
 // Allocate memory for the field descriptor...
 pFields := AllocMem(Table.FieldCount * sizeof(FLDDesc));
 // Allocate memory for the operation descriptor...
 pOp := AllocMem(Table.FieldCount * sizeof(CROpType));
 try
   // Set the pointer to the index in the operation descriptor to put
   // crMODIFY (This means a modification to the record is going to happen)...
   Inc(pOp, Field.Index);
   pOp^ := crMODIFY;
   Dec(pOp, Field.Index);
   // Fill the field descriptor with the existing field information...
   Check(DbiGetFieldDescs(Table.Handle, pFields));
   // Set the pointer to the index in the field descriptor to make the
   // midifications to the field
   Inc(pFields, Field.Index);

   // If the szName portion of the ChangeRec has something in it, change it...
   if StrLen(Rec.szName) > 0 then
     pFields^.szName := Rec.szName;
   // If the iType portion of the ChangeRec has something in it, change it...
   if Rec.iType > 0 then
     pFields^.iFldType := Rec.iType;
   // If the iSubType portion of the ChangeRec has something in it, change it...
   if Rec.iSubType > 0 then
     pFields^.iSubType := Rec.iSubType;
   // If the iLength portion of the ChangeRec has something in it, change it...
   if Rec.iLength > 0 then
     pFields^.iUnits1 := Rec.iLength;
   // If the iPrecision portion of the ChangeRec has something in it, change it...
   if Rec.iPrecision > 0 then
     pFields^.iUnits2 := Rec.iPrecision;
   Dec(pFields, Field.Index);

   for B := 1 to Table.FieldCount do begin
     pFields^.iFldNum := B;
     Inc(pFields, 1);
   end;
   Dec(pFields, Table.FieldCount);

   // Blank out the structure...
   FillChar(TableDesc, sizeof(TableDesc), 0);
   //  Get the database handle from the table's cursor handle...
   Check(DbiGetObjFromObj(hDBIObj(Table.Handle), objDATABASE, hDBIObj(hDb)));
   // Put the table name in the table descriptor...
   StrPCopy(TableDesc.szTblName, Table.TableName);
   // Put the table type in the table descriptor...
   StrPCopy(TableDesc.szTblType, Props.szTableType);
   // The following three lines are necessary when doing any field restructure
   // operations on a table...

   // Set the field count for the table
   TableDesc.iFldCount := Table.FieldCount;
   // Link the operation descriptor to the table descriptor...
   TableDesc.pecrFldOp := pOp;
   // Link the field descriptor to the table descriptor...
   TableDesc.pFldDesc := pFields;
   // Close the table so the restructure can complete...
   Table.Close;
   // Call DbiDoRestructure...
   Check(DbiDoRestructure(hDb, 1, @TableDesc, nil, nil, nil, FALSE));
 finally
   if pFields <> nil then
     FreeMem(pFields);
   if pOp <> nil then
     FreeMem(pOp);
 end;
end;

//paste end
//change a field

procedure TForm1.Button4Click(Sender: TObject);
var CR : ChangeRec;
begin
 Table1.Open;
 FillChar(CR,SizeOf(CR),0);
 CR.iType := fldBlob;
 CR.iSubType := fldstMemo;
 ChangeField(Table1,Table1.FieldbyName('F2'),CR);
 Table1.Close;
end;

hope it helps

meikl ;-)
0
 
LVL 27

Expert Comment

by:kretzschmar
Comment Utility
0
 

Author Comment

by:Vanessa
Comment Utility
Sorry Dr Delphi I didn't make it clear that I would not be running the db application while using the update application.

Would it be easier to do this through a query?

0
 
LVL 27

Expert Comment

by:kretzschmar
Comment Utility
>Would it be easier to do this through a query?
nope, did not work->type mismatch->Alpha<>memo
0
 

Author Comment

by:Vanessa
Comment Utility
Additionally I will be making about 30 changes (I know that sounds bad but the client has asked for some radical changes) and I want the update application to be very stable.
0
 
LVL 27

Expert Comment

by:kretzschmar
Comment Utility
30 changes!
code a migration-app and a empty table with the desired structure, in your app iterate through the records, do your fieldmappings and post the record to your empty table

depending on the complexity of changes you could use the tbatchmove-component

meikl ;-)
0
How your wiki can always stay up-to-date

Quip doubles as a “living” wiki and a project management tool that evolves with your organization. As you finish projects in Quip, the work remains, easily accessible to all team members, new and old.
- Increase transparency
- Onboard new hires faster
- Access from mobile/offline

 
LVL 15

Expert Comment

by:simonet
Comment Utility
Wouldn't just a few SQL statements work?

ALTER TABLE1 add Content2 Memo;

UPDATE TABLE1 set Content2 = Content;

ALTER TABLE1 drop Content;

ALTER TABLE1 add Content Memo;

UPDATE TABLE1 set Content = Content2;

ALTER TABLE1 drop Content2;


That's all there is to it, in my opinion. Just 6 SQL statements would do it quickly, w/o messing with BDE.

If you're working with more changes, they can (in some cases) all be worked on the same query, for example, creating/dropping several temp columns at once, running several updates in the same table at once, and so on.

yours,

Alex
0
 
LVL 27

Expert Comment

by:kretzschmar
Comment Utility
are you sure, alex?

you can't drop columns
0
 

Author Comment

by:Vanessa
Comment Utility
ALEX and others,

Below is the code I am using for just one update.

It falls over on Update line  message = "Invalid use of keyword line 2 TOKEN UPDATE"

I am not sure what I am doing wrong.

Additionally do I use BLOB as MEMO is unsupported?

Query1.SQL.Clear;
Query1.SQL.Add('ALTER TABLE "VessInfo.DB" ADD CFTM BLOB');
Query1.SQL.Add('UPDATE TABLE "VessInfo.db" SET CFTM = CFT');
Query1.SQL.Add('ALTER TABLE "VessInfo.DB"');
Query1.SQL.Add('DROP CFT');
Query1.SQL.Add('ALTER TABLE "VessInfo.DB"');
Query1.SQL.Add('ADD CFTM BLOB');
Query1.SQL.Add('UPDATE TABLE "VessInfo.DB"');
Query1.SQL.Add('SET CFT = CFTM');
Query1.SQL.Add('ALTER TABLE "VessInfo.DB"');
Query1.SQL.Add('DROP CFTM');
Query1.ExecSQL

Cheers

Vanessa
0
 
LVL 15

Accepted Solution

by:
simonet earned 50 total points
Comment Utility
The correct syntax is:

Query1.SQL.Add('UPDATE "VessInfo.db" SET CFTM = CFT');


It's simply

UPDATE tablename

and not

UPDATE TABLE tablename


BEsides, you may not be able to run everything in a single pass, because BDE/Paradox only accepts one statement at a time.

Yorus,

Alex
0
 
LVL 1

Expert Comment

by:Moondancer
Comment Utility
This question is reasonably current, others are not.  All of them need your attention.  ADMINISTRATION WILL BE CONTACTING YOU SHORTLY.  Moderators Computer101 or Netminder will return to finalize these if they are still open in 14 days.  Experts, please post closing recommendations before that time.

Below are your open questions as of today.  Questions which have been inactive for 21 days or longer are considered to be abandoned and for those, your options are:
1. Accept a Comment As Answer (use the button next to the Expert's name).
2. Close the question if the information was not useful to you, but may help others. You must tell the participants why you wish to do this, and allow for Expert response.  This choice will include a refund to you, and will move this question to our PAQ (Previously Asked Question) database.  If you found information outside this question thread, please add it.
3. Ask Community Support to help split points between participating experts, or just comment here with details and we'll respond with the process.
4. Delete the question (if it has no potential value for others).
   --> Post comments for expert of your intention to delete and why
   --> YOU CANNOT DELETE A QUESTION with comments; special handling by a Moderator is required.

For special handling needs, please post a zero point question in the link below and include the URL (question QID/link) that it regards with details.
http://www.experts-exchange.com/jsp/qList.jsp?ta=commspt
 
Please click this link for Help Desk, Guidelines/Member Agreement and the Question/Answer process.  http://www.experts-exchange.com/jsp/cmtyHelpDesk.jsp

Click you Member Profile to view your question history and please keep them updated. If you are a KnowledgePro user, use the Power Search option to find them.  

Questions which are LOCKED with a Proposed Answer but do not help you, should be rejected with comments added.  When you grade the question less than an A, please comment as to why.  This helps all involved, as well as others who may access this item in the future.  PLEASE DO NOT AWARD POINTS TO ME.

To view your open questions, please click the following link(s) and keep them all current with updates.
http://www.experts-exchange.com/questions/Q.20185150.html
http://www.experts-exchange.com/questions/Q.20185271.html
http://www.experts-exchange.com/questions/Q.20292502.html



*****  E X P E R T S    P L E A S E  ******  Leave your closing recommendations.
If you are interested in the cleanup effort, please click this link
http://www.experts-exchange.com/jsp/qManageQuestion.jsp?ta=commspt&qid=20274643
POINTS FOR EXPERTS awaiting comments are listed in the link below
http://www.experts-exchange.com/commspt/Q.20277028.html
 
Moderators will finalize this question if in @14 days Asker has not responded.  This will be moved to the PAQ (Previously Asked Questions) at zero points, deleted or awarded.
 
Thanks everyone.
Moondancer
Moderator @ Experts Exchange
0
 
LVL 1

Expert Comment

by:pnh73
Comment Utility
No comment has been added lately, so it's time to clean up this TA.
I will leave a recommendation in the Cleanup topic area that this question is:

Accept answer from simonet

Please leave any comments here within the next seven days.
 
PLEASE DO NOT ACCEPT THIS COMMENT AS AN ANSWER!
 
Paul (pnh73)
EE Cleanup Volunteer
0
 
LVL 27

Expert Comment

by:kretzschmar
Comment Utility
didn't agree
0
 
LVL 1

Expert Comment

by:pnh73
Comment Utility
Please can you explain why you dont agree, then I may consider your objection.

Paul (pnh73)
EE Cleanup Volunteer
0

Featured Post

Find Ransomware Secrets With All-Source Analysis

Ransomware has become a major concern for organizations; its prevalence has grown due to past successes achieved by threat actors. While each ransomware variant is different, we’ve seen some common tactics and trends used among the authors of the malware.

Join & Write a Comment

This article explains how to create forms/units independent of other forms/units object names in a delphi project. Have you ever created a form for user input in a Delphi project and then had the need to have that same form in a other Delphi proj…
In my programming career I have only very rarely run into situations where operator overloading would be of any use in my work.  Normally those situations involved math with either overly large numbers (hundreds of thousands of digits or accuracy re…
Illustrator's Shape Builder tool will let you combine shapes visually and interactively. This video shows the Mac version, but the tool works the same way in Windows. To follow along with this video, you can draw your own shapes or download the file…
This tutorial demonstrates a quick way of adding group price to multiple Magento products.

743 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

17 Experts available now in Live!

Get 1:1 Help Now