Icon View Thread

The following is the text of the current message along with any replies.
Messages 1 to 1 of 1 total
Thread Copy server DB data to local Elevate DB
Wed, Jun 10 2009 9:41 AMPermanent Link

Daniel Kram
I had to build a system to take from any "server" type DB, like MySQL or MS SQL Server, for example, and copy certain tables contents down to a local
ElevateDB. Note, for those of you who do not know, Elevate Server has a synchronization mechanism built in, so you should probably use it, instead IF you
have an elevate server DB - in my case, I did not.

So the idea is fairly simple: Have one or more tables to copy so what does it do?
First, check the server to see if any data even exists in the table (I had some wih no data for long periods of time)
Second, I dropped and created the local Elevate table. The primary reason for this was so I did not need to try and manage the table structure of the local
DB, only the server, as the local would be updated to the server structure at this point.
Third, load the data from the query results in step 1 above.

Now here is the meat of the post. What the code below will do, is build a series of SQL insert statements
 take data in a server query result set (F_objDBWork.qryWork)
 Build a list of field values (first for loop)
 Set the destination, local table, to receive the data (TEDBQuery(F_objDBWork.F_objLocalDB.qryWork)) I typed cast this because the code I wrote defines
my query objects as just TDataSets. This way, they instantiated object can go to Elevate or MySQL or any other descendent of TDataset.

 // build the beginning part of the SQL (one time needed only)
 with F_objDBWork.qryWork do
 begin
   sSQL := 'INSERT INTO ' + p_sTableName + ' VALUES (';
   for nCount:=0 to FieldCount-1 do
      begin
      if (nCount > 0) then
         sSQL := sSQL + ', ';
      sSQL := sSQL + ':' + Fields[nCount].FieldName;
      end;
   sSQL := sSQL + ')';
   TEDBQuery(F_objDBWork.F_objLocalDB.qryWork).SQL.Text := sSQL;
   TEDBQuery(F_objDBWork.F_objLocalDB.qryWork).Prepare;
   First;
   // iterate through all the rows in the above query and add the rows locally
   while (not EOF) do
      begin
      for nCount := 0 to FieldCount-1 do
         TEDBQuery(F_objDBWork.F_objLocalDB.qryWork).Params[nCount].AssignField(Fields[nCount]);
      TEDBQuery(F_objDBWork.F_objLocalDB.qryWork).ExecSQL;
      Next;
      end;
   end;

Tim Young, actually sent me a variation of this (I revised it to work within my application) but the bulk of it is Tim Young's - Thank you Tim.

The method above improved execution time by 90 percent!

If you are interested, here is the code to create a table at runtime
 sSQL    := 'CREATE TABLE ' + p_sTableName + ' (';
 // create the table, using the table info from the server object
 for nCount := 0 to objDBServer.F_objDBWork.qryWork.FieldList.Count - 1 do
 begin
   if (nCount > 0) then
   begin
       sSQL     := sSQL + ', ';
   end;
   // column name
   sSQL    := sSQL + AnsiQuotedStr(objDBServer.F_objDBWork.qryWork.FieldList.Fields
[nCount].DisplayName,objDBServer.F_objDBWork.chrFieldSeperator);
   // column type and size
   case objDBServer.F_objDBWork.qryWork.FieldDefs.Items[nCount].DataType of
     ftMemo:        sSQL := sSQL + ' CLOB COLLATE "ANSI"';
     ftAutoInc:     sSQL := sSQL + ' INTEGER ';
     ftSmallint:    sSQL := sSQL + ' SMALLINT ';
     ftInteger:     sSQL := sSQL + ' INTEGER ';
     ftBoolean:     sSQL := sSQL + ' BOOLEAN ';
     ftWord:        sSQL := sSQL + ' SMALLINT ';
     ftFixedChar:   sSQL := sSQL + ' CHAR (' + inttostr(objDBServer.F_objDBWork.qryWork.FieldDefs.Items[nCount].Size) + ') COLLATE "ANSI"';
     ftString:      sSQL := sSQL + ' VARCHAR(' + inttostr(objDBServer.F_objDBWork.qryWork.FieldDefs.Items[nCount].Size) + ') COLLATE "ANSI"';
     ftWideString:  sSQL := sSQL + ' VARCHAR(' + inttostr(objDBServer.F_objDBWork.qryWork.FieldDefs.Items[nCount].Size) + ') COLLATE "ANSI"';
     ftBCD:         sSQL := sSQL + ' DECIMAL(20,2) ';
     ftFloat:       sSQL := sSQL + ' DECIMAL(20,2) ';
     ftDateTime:    sSQL := sSQL + ' TIMESTAMP ';
     // from here and down are untested as of 12/16/2008
     ftCurrency:    sSQL := sSQL + ' DECIMAL(20,2) ';
     ftDate:        sSQL := sSQL + ' TIMESTAMP ';
     ftTimeStamp:   sSQL := sSQL + ' TIMESTAMP ';
     // there are several others not yet coded
   end;
 end;
 sSQL  := sSQL + ')';
 TEDBQuery(F_objDBWork.F_objLocalDB.qryWork).SQL.Text := sSQL;
 TEDBQuery(F_objDBWork.F_objLocalDB.qryWork).Prepare;
 TEDBQuery(F_objDBWork.F_objLocalDB.qryWork).ExecSQL;


Take care
Image