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 | >>