Data comparer using cursors full example

<< | IBEBlock | >>

Data comparer using cursors full example

 execute ibeblock (
   ProcessInserts boolean = TRUE,
    ProcessUpdates boolean = TRUE,
    ProcessDeletes boolean = TRUE)
 returns (
    InsertedRecs integer = 0 comment 'Records inserted',
    UpdatedRecs integer = 0 comment 'Records updated',
    DeletedRecs integer = 0 comment 'Records deleted',
    TotalTime double precision = 0 comment 'Time spent (seconds)')
 as
 begin
     RecNum = 5000; -- How many records will be inserted into our test table

     if (not ibec_fileexists('d:\MasterDB.fdb')) then
       ibec_CreateDatabase(__ctFirebird, 'DBName="localhost:d:\MasterDB.fdb";
                                ClientLib="fbclient.dll";
                                User=SYSDBA; Password=masterkey; PageSize=16384;
                                DefaultCharset=UTF8; SQLDialect=3');

     if (not ibec_fileexists('d:\SubscriberDB.fdb')) then
       ibec_CreateDatabase(__ctFirebird, 'DBName="localhost:d:\SubscriberDB.fdb";
                                ClientLib="fbclient.dll";
                                User=SYSDBA; Password=masterkey; PageSize=16384;
                                DefaultCharset=UTF8; SQLDialect=3');

     DropStmt = 'drop table IBE$$TEST_DATA';
     CreateStmt =
       'create table IBE$$TEST_DATA (
         ID integer not null,
         ID2 varchar(20) not null,
         F_INTEGER integer,
         F_VARCHAR varchar(100),
         F_DATE date,
         F_TIME time,
         F_TIMESTAMP timestamp,
         F_NUMERIC numeric(15,2),
         F_BOOL char(1) check (F_BOOL in (''T'', ''F'')),
         F_BLOB blob sub_type 1,
         F_SEASON varchar(15) check(F_SEASON in (''Spring'', ''Summer'', ''Autumn'', ''Winter'')))';

      AlterStmt =
       'alter table IBE$$TEST_DATA add constraint PK_TEST_DATA primary key (ID)';

      MasterDB = ibec_CreateConnection(__ctFirebird,'DBName="localhost:d:\MasterDB.FDB";
                                  ClientLib=fbclient.dll;
                                  user=SYSDBA; password=masterkey; names=UTF8; sqldialect=3');

      SubscriberDB = ibec_CreateConnection(__ctFirebird,'DBName="localhost:d:\SubscriberDB.FDB";
                                  ClientLib=fbclient.dll;
                                  user=SYSDBA; password=masterkey; names=UTF8; sqldialect=3');

      ibec_UseConnection(MasterDB);
      --Let's drop table for our example, if you test it repeatedly
      if (exists(select rdb$relation_name from rdb$relations where rdb$relation_name = 'IBE$$TEST_DATA')) then
      begin
        execute statement :DropStmt;
        commit;
      end
      if (not exists(select rdb$relation_name from rdb$relations where rdb$relation_name = 'IBE$$TEST_DATA')) then
      begin
        execute statement :CreateStmt;
        commit;
        execute statement :AlterStmt;
        commit;
        i = 0;
        while (i < RecNum) do
        begin
              fid2    = ibec_randomstring(1,20,65,90);
              fint    = ibec_random2(1, 100000);
              fvarc   = ibec_randomstring(1,100,65,90);
              fdate   = ibec_random2(20000,40000);
              ftime   = ibec_random(0);
              ftimest = ibec_random2(20000,40000) + ibec_random(0);
              fnum    = ibec_random2(1,40000) + ibec_random(0);
              fbool   = ibec_randomval('T','F');
              fblob   = ibec_randomstring(500, 1000, 65, 90);
              fseason = ibec_randomval('Spring', 'Summer', 'Autumn', 'Winter');

              insert into IBE$$TEST_DATA values (:i, :fid2, :fint, :fvarc, :fdate, :ftime, :ftimest, :fnum, :fbool, :fblob, :fseason);

              i = i + 1;
              if (ibec_mod(i, 500) = 0) then
              begin
                 ibec_progress(i || ' records inserted...');
                 commit;
              end;
        end;
        commit;
      end;
      --Let's drop table for our example, if you test it repeatedly
      ibec_UseConnection(SubscriberDB);
      if (exists(select rdb$relation_name from rdb$relations where rdb$relation_name = 'IBE$$TEST_DATA')) then
      begin
         execute statement :DropStmt;
         commit;
      end

      if (not exists(select rdb$relation_name from rdb$relations where rdb$relation_name =  'IBE$$TEST_DATA')) then
      begin
        execute statement :CreateStmt;
        commit;
        execute statement :AlterStmt;
        commit;

        ibec_UseConnection(MasterDB);

        i = 0;
        k = 0;

        for select * from IBE$$TEST_DATA
        into vals
        do
        begin
           ibec_UseConnection(SubscriberDB);
           k = k + 1; -- Just a counter...
           if (ibec_mod(k,100) <> 0) then 
           begin
              if (ibec_mod(i,10) = 0) then
                vals[7] = null;
              if (ibec_mod(i,30) = 0) then 
                vals[9] = ibec_randomstring(500, 1000, 65, 90);
              insert into SubscriberDB.IBE$$TEST_DATA values :vals;
              i = i + 1;
              if (ibec_mod(i, 500) = 0) then
              begin
                 ibec_progress(i || ' records inserted...');
                 commit;
              end
           end
        end
        ibec_UseConnection(SubscriberDB);
        commit;

        i = k + 1;
        while (i < (RecNum + 1000 + 1)) do
        begin
           fid2    = ibec_randomstring(1,20,65,90);
           fint    = ibec_random2(1, 100000);
           fvarc   = ibec_randomstring(1,100,65,90);
           fdate   = ibec_random2(20000,40000);
           ftime   = ibec_random(0);
           ftimest = ibec_random2(20000,40000) + ibec_random(0);
           fnum    = ibec_random2(1,40000) + ibec_random(0);
           fbool   = ibec_randomval('T','F');
           fblob   = ibec_randomstring(500, 1000, 65, 90);
           fseason = ibec_randomval('Spring', 'Summer', 'Autumn', 'Winter');

           insert into IBE$$TEST_DATA values (:i, :fid2, :fint, :fvarc, :fdate, :ftime, :ftimest, :fnum, :fbool, :fblob, :fseason);

           if (ibec_mod(i, 500) = 0) then
           begin
              ibec_progress(i || ' records inserted...');
              commit;
           end
           i = i + 1;
        end
        commit;
      end
      use MasterDB;
      i = 0;
      for select i.rdb$field_name
      from rdb$relation_constraints rc, rdb$index_segments i, rdb$indices idx
      where (i.rdb$index_name = rc.rdb$index_name) and
          (idx.rdb$index_name = rc.rdb$index_name) and
          (rc.rdb$constraint_type = 'PRIMARY KEY') and
          (rc.rdb$relation_name = 'IBE$$TEST_DATA')
      order by i.rdb$field_position
      into fldname
      do
      begin
        PKFields[i] = ibec_trim(fldname);
        i = i + 1;
      end
      SelStmt = 'select rdb$field_name
               from rdb$relation_fields
               where (rdb$relation_name = ''IBE$$TEST_DATA'')';

      i = 0;
      HighDim = ibec_high(PKFields);
      for i = 0 to HighDim do
         SelStmt = SelStmt || ' and (rdb$field_name <> ' || ibec_QuotedStr(PKFields[i], '''') || ')';

      SelStmt = SelStmt || ' order by rdb$field_position';

      i = 0;
      for execute statement :SelStmt
      into :s
      do
      begin
         NonPKFields[i] = ibec_trim(:s);
         i = i + 1;
      end
    --SelStmt will be used to retrieve data
    --UpdStmt will be used to update the second table if two records differ:
      SelStmt = '';
      UpdStmt = 'update ibe$$test_data set ';
      WhereClause = ' where ';

      HighDim = ibec_high(NonPKFields);
      for i = 0 to HighDim do
      begin
         SelStmt = SelStmt || NonPKFields[i];
         SelStmt = SelStmt || ', ';
         UpdStmt = UpdStmt || ibec_chr(13) || NonPKFields[i] || ' = :' || NonPKFields[i];
         if (i < HighDim) then
            UpdStmt = UpdStmt || ', ';
      end
      HighDim = ibec_high(PKFields);
      for i = 0 to HighDim do
      begin
         SelStmt = SelStmt || ibec_trim(PKFields[i]);
         WhereClause = WhereClause || '(' || ibec_trim(PKFields[i]) || ' = :' || ibec_trim(PKFields[i]) || ')';
         if (i < HighDim) then
         begin
            SelStmt = SelStmt || ', ';
            WhereClause = WhereClause || ' and ';
         end
      end

      SelStmt = 'select ' || SelStmt || ' from IBE$$TEST_DATA order by ';

      for i = 0 to HighDim do
      begin
         SelStmt = SelStmt || ibec_trim(PKFields[i]);
         if (i < HighDim) then
            SelStmt = SelStmt || ', ';
      end

      PKFieldCount = ibec_high(PKFields)+1;
      PKFieldIndex = ibec_high(NonPKFields)+1;

      StartTime = ibec_gettickcount(); -- Note the time...

      MasterCR = ibec_cr_OpenCursor(MasterDB, SelStmt);
      SubscriberCR = ibec_cr_OpenCursor(SubscriberDB, SelStmt);

      InsFields = ''; InsValues = '';
      FldCount = ibec_cr_FieldCount(SubscriberCR);
      for i = 0 to (FldCount-1) do
      begin
         FldName = ibec_Trim(ibec_cr_FieldName(SubscriberCR, i));
         InsFields = InsFields || FldName;
         InsValues = InsValues || ':' || FldName;
         if (i < (FldCount-1)) then
         begin
            InsFields = InsFields || ', ';
            InsValues = InsValues || ', ';
         end
      end
      InsStmt = 'insert into ibe$$test_data (' || InsFields || ') values (' || InsValues || ')';

      ibec_UseConnection(SubscriberDB);

      while (not (ibec_cr_Eof(MasterCR) and ibec_cr_Eof(SubscriberCR))) do
      begin
         CompResult = 0;
         if (ibec_cr_Eof(MasterCR)) then
            CompResult = 1;
         else if (ibec_cr_Eof(SubscriberCR)) then
            CompResult = -1;
         else
         begin
            ibec_cr_Fetch(MasterCR, MasterPK, PKFieldIndex, PKFieldCount);
            ibec_cr_Fetch(SubscriberCR, SubscriberPK, PKFieldIndex, PKFieldCount);
            CompResult = ibec_CmpRecords2(MasterPK, SubscriberPK);
         end

         if (ProcessUpdates and (CompResult = 0)) then
         begin
            ibec_cr_Fetch(MasterCR, MasterVals, 0, PKFieldIndex);
            ibec_cr_Fetch(SubscriberCR, SubscriberVals, 0, PKFieldIndex);
            CompResult = ibec_CmpRecords(MasterVals, SubscriberVals);
            if (CompResult <> -1) then
            begin
               UpdatedRecs = UpdatedRecs + 1;
               ibec_progress('Record must be updated...');
               ibec_cr_Fetch(MasterCR, MasterVals, 0, null);
               execute statement :UpdStmt || WhereClause values :MasterVals;
            end

            ibec_cr_Next(MasterCR);
            ibec_cr_Next(SubscriberCR);
         end
         else if (ProcessInserts and (CompResult < 0)) then
         begin
            InsertedRecs = InsertedRecs + 1;
            ibec_progress('Record must be inserted...');
            ibec_cr_Fetch(MasterCR, MasterVals, 0, null);
            execute statement :InsStmt values :MasterVals;
            ibec_cr_Next(MasterCR);
         end
         else if (ProcessDeletes and (CompResult > 0)) then
         begin
            DeletedRecs = DeletedRecs + 1;
            ibec_progress('Record must be deleted...');
            ibec_cr_Fetch(SubscriberCR, SubscriberPK, PKFieldIndex, PKFieldCount);
            execute statement 'delete from ibe$$test_data ' || WhereClause values :SubscriberPK;
           ibec_cr_Next(SubscriberCR);
         end;
      end

      ibec_cr_CloseCursor(MasterCR);
      ibec_cr_CloseCursor(SubscriberCR);

      commit;
      close connection MasterDB;
      close connection SubscriberDB;
      EndTime = ibec_gettickcount();
      TotalTime = (EndTime - StartTime) / 1000;
      suspend;
 end;

back to top of page
<< | IBEBlock | >>