ODI operation details
Consistent CDC (Last Update Date) Synchronized Data
Add CDC
1. Check the database version
DECLARE -- Validating KM options dbVersion1 NUMBER(2,0); dbVersion2 NUMBER(2,0); BEGIN -- Verify RDBMS version select case when upper(name) = 'COMPATIBLE' then to_number(substr(value, 1, instr(value, '.',1,1)-1)) else null end v0, case when upper(name) = 'COMPATIBLE' then to_number(substr(value, instr(value, '.',1,1)+1, instr(value, '.',1,2)-instr(value, '.',1,1)-1)) else null end v1 into dbVersion1, dbVersion2 from v$parameter where upper(name) = 'COMPATIBLE'; IF dbVersion1 < 9 THEN raise_application_error(-20101, 'ODIKM-ORA-10000: You are using RDBMS version '||dbVersion1||'.'||dbVersion2||'. This version does not support JKM COMPATIBLE= 9.'); END IF; END;
2. Get connection
import java.sql as sql import java.lang as lang # Connect to the Source Database ie the one that hosts the journalized tables myCon = odiRef.getJDBCConnection("SRC") # Create the list of Subscribers for a CDC Set lstSbs = [] lstSbs.append('Weichao')
3. Delete the CDC value in SNP_CDC_SUBS
delCmd = """ delete from FUSION.SNP_CDC_SUBS CDC where CDC.CDC_SET_NAME = 'FUSION.FUSIONTABLEUPDATEDEMO' and CDC.CDC_SUBSCRIBER = ? """ # Prepare the delete prepDelStmt = myCon.prepareStatement(delCmd) # Execute it for each subscriber for sbs in lstSbs: prepDelStmt.setString(1, sbs) nbRows = prepDelStmt.executeUpdate() prepDelStmt.close() # Commit the updates myCon.commit()
4. Every time we change the contents of this table, we recalculate the statistics.
/* After each change on the content of this table we recompute the statistics */ /* Statistics are always up to date on this table */ begin dbms_stats.gather_table_stats( ownname => 'FUSION', tabname => 'SNP_CDC_SUBS', estimate_percent => dbms_stats.auto_sample_size ); end;
5. Close the connection
myCon.close()
Add subscription
1. Check the database version
DECLARE -- Validating KM options dbVersion1 NUMBER(2,0); dbVersion2 NUMBER(2,0); BEGIN -- Verify RDBMS version select case when upper(name) = 'COMPATIBLE' then to_number(substr(value, 1, instr(value, '.',1,1)-1)) else null end v0, case when upper(name) = 'COMPATIBLE' then to_number(substr(value, instr(value, '.',1,1)+1, instr(value, '.',1,2)-instr(value, '.',1,1)-1)) else null end v1 into dbVersion1, dbVersion2 from v$parameter where upper(name) = 'COMPATIBLE'; IF dbVersion1 < 9 THEN raise_application_error(-20101, 'ODIKM-ORA-10000: You are using RDBMS version '||dbVersion1||'.'||dbVersion2||'. This version does not support JKM COMPATIBLE= 9.'); END IF; END;
2. Setting parameters to get database connection
import java.sql as sql import java.lang as lang # Connect to the Source Database ie the one that hosts the journalized tables myCon = odiRef.getJDBCConnection("SRC") # Create the list of Subscribers for a CDC Set lstSbs = [] lstSbs.append('Zero')
3. Create table SNP_CDC_SUBS, because it has been created, an exception will be reported.
/* This table is created in the work physical schema set as default for the Data server */ create table FUSION.SNP_CDC_SUBS ( CDC_SET_NAME VARCHAR2(255 CHAR) not null, /* Name of the CDC Set (ODI model code following the Local Mask syntax) */ CDC_SUBSCRIBER VARCHAR2(400 CHAR) not null, /* Name of the subscriber who subscribed to the CDC Set */ CDC_REFDATE DATE not null, /* Last update of the record */ MIN_WINDOW_ID NUMBER(20) not null, /* Window Ids under this one should be ignored */ MAX_WINDOW_ID NUMBER(20) not null, /* Maximum Window Id used by this subscription */ MAX_WINDOW_ID_DEL NUMBER(20) not null, /* Maximum Window Id to take into consideration when looking at consistency for deletes */ MAX_WINDOW_ID_INS NUMBER(20) not null, /* Maximum Window Id to take into consideration when looking at consistency for inserts / updates */ CDC_ROW_COUNT NUMBER(10) not null, /* Number of rows in the journalizing tables for this subscription */ constraint PK_SNP_CDC_SBS primary key (CDC_SET_NAME, CDC_SUBSCRIBER) )
The JKM execution process is as follows. Ignoring errors is checked, so the creation errors above are ignored.
4. Setting field length
alter table FUSION.SNP_CDC_SUBS modify (CDC_SUBSCRIBER VARCHAR2(400 CHAR))
5. Setting field length table does not exist and error will be reported.
alter table FUSION.SNP_CDC_SUBS_AE modify (CDC_SUBSCRIBER VARCHAR2(400 CHAR))
6. Creating CDC_SET table table already exists and will report errors
/* This table is created in the work physical schema set as default for the Data server */ create table FUSION.SNP_CDC_SET ( CDC_SET_NAME VARCHAR2(255 CHAR) not null, /* Name of the CDC Set (ODI model code following the Local Mask syntax) */ CUR_WINDOW_ID NUMBER(20) not null, /* Last window Id that has been used */ CUR_WINDOW_ID_DEL NUMBER(20) not null, /* Last Window Id used to compute delete consitency */ CUR_WINDOW_ID_INS NUMBER(20) not null, /* Last Window Id used to compute inert / update consitency */ RETRIEVE_DATA VARCHAR2(2000 CHAR) null, /* Command to execute in order to retrieve the journal data (used by the OdiRetrieveJournalData tool) */ REFRESH_ROW_COUNT VARCHAR2(2000 CHAR) null, /* Command to execute in order to refresh the row count(used by the OdiRefreshJournalData tool) */ constraint PK_SNP_CDC_SET primary key (CDC_SET_NAME) ) /* This table is created in the work physical schema set as default for the Data server */ create table FUSION.SNP_CDC_SET ( CDC_SET_NAME VARCHAR2(255 CHAR) not null, /* Name of the CDC Set (ODI model code following the Local Mask syntax) */ CUR_WINDOW_ID NUMBER(20) not null, /* Last window Id that has been used */ CUR_WINDOW_ID_DEL NUMBER(20) not null, /* Last Window Id used to compute delete consitency */ CUR_WINDOW_ID_INS NUMBER(20) not null, /* Last Window Id used to compute inert / update consitency */ RETRIEVE_DATA VARCHAR2(2000 CHAR) null, /* Command to execute in order to retrieve the journal data (used by the OdiRetrieveJournalData tool) */ REFRESH_ROW_COUNT VARCHAR2(2000 CHAR) null, /* Command to execute in order to refresh the row count(used by the OdiRefreshJournalData tool) */ constraint PK_SNP_CDC_SET primary key (CDC_SET_NAME) )
7. Create table SNP_CDC_SET_TABLE already exists and will report errors
/* This table is created in the work physical schema set as default for the Data server */ create table FUSION.SNP_CDC_SET_TABLE ( CDC_SET_NAME VARCHAR2(255 CHAR) not null, /* Name of the CDC Set (ODI model code following the Local Mask syntax) */ FULL_TABLE_NAME VARCHAR2(255 CHAR) not null, /* Complete name of the journalized table */ FULL_DATA_VIEW VARCHAR2(255 CHAR) not null, /* Complete name of the journalizing data view */ RETRIEVE_DATA VARCHAR2(2000 CHAR) null, /* Command to execute to retrieve the journal data (used by the OdiRetrieveJournalData tool) */ REFRESH_ROW_COUNT VARCHAR2(2000 CHAR) null, /* Command to execute to refresh the row count (used by the OdiRefreshRowCount tool) */ CDC_LAST_DATE TIMESTAMP, CDC_CURRENT_DATE TIMESTAMP, constraint PK_SNP_CDC_TBL primary key (FULL_TABLE_NAME) )
8.SNP_CDC_SET_TABLE add column has been added, error will be reported
alter table FUSION.SNP_CDC_SET_TABLE add ( CDC_LAST_DATE TIMESTAMP, CDC_CURRENT_DATE TIMESTAMP )
9. Create table SNP_CDC_OBJECTS table has been created and error will be reported
/* This table is created in the work physical schema set as default for the Data server */ create table FUSION.SNP_CDC_OBJECTS ( FULL_TABLE_NAME VARCHAR2(255 CHAR) not null, /* Complete name of the journalized table */ CDC_OBJECT_TYPE VARCHAR2(35 CHAR) not null, /* Type of the object in the CDC framework */ FULL_OBJECT_NAME VARCHAR2(255 CHAR) not null, /* Complete name of the object */ DB_OBJECT_TYPE VARCHAR2(35 CHAR) null, /* RDBMS type of the object (ex : TABLE, VIEW, TRIGGER) */ constraint PK_SNP_CDC_OBJ primary key (FULL_TABLE_NAME, CDC_OBJECT_TYPE) )
10. Add to the CDC_SET table
insert into FUSION.SNP_CDC_SET ( CDC_SET_NAME, CUR_WINDOW_ID, CUR_WINDOW_ID_DEL, CUR_WINDOW_ID_INS, RETRIEVE_DATA, REFRESH_ROW_COUNT ) values ( /* CDC_SET_NAME */ 'FUSION.FUSIONTABLEUPDATEDEMO', /* CUR_WINDOW_ID */ -1, /* CUR_WINDOW_ID_DEL */ -1, /* CUR_WINDOW_ID_INS */ -1, /* RETRIEVE_DATA */ NULL, /* REFRESH_ROW_COUNT */ 'update FUSION.SNP_CDC_SUBS set CDC_ROW_COUNT = 0 ' || 'where CDC_SUBSCRIBER = ''$$SUBSCRIBER_NAME$$'' ' || 'and CDC_SET_NAME = ''FUSION.FUSIONTABLEUPDATEDEMO'' ' )
11. Update the SNP_CDC_SET table
update FUSION.SNP_CDC_SET CDC set CDC.RETRIEVE_DATA = NULL, CDC.REFRESH_ROW_COUNT = 'update FUSION.SNP_CDC_SUBS set CDC_ROW_COUNT = 0 ' || 'where CDC_SUBSCRIBER = ''$$SUBSCRIBER_NAME$$'' ' || 'and CDC_SET_NAME = ''FUSION.FUSIONTABLEUPDATEDEMO'' ' where CDC.CDC_SET_NAME = 'FUSION.FUSIONTABLEUPDATEDEMO'
12. Insert data into SNP_CDC_SUBS
insCmd = """ insert into FUSION.SNP_CDC_SUBS ( CDC_SET_NAME, CDC_SUBSCRIBER, CDC_REFDATE, MIN_WINDOW_ID, MAX_WINDOW_ID, MAX_WINDOW_ID_DEL, MAX_WINDOW_ID_INS, CDC_ROW_COUNT ) select /* CDC_SET_NAME */ 'FUSION.FUSIONTABLEUPDATEDEMO', /* CDC_SUBSCRIBER */ ?, /* CDC_REFDATE */ sysdate, /* MIN_WINDOW_ID */ CDC.CUR_WINDOW_ID, /* MAX_WINDOW_ID */ -1, /* MAX_WINDOW_ID_DEL */ -1, /* MAX_WINDOW_ID_INS */ -1, /* CDC_ROW_COUNT */ 0 from FUSION.SNP_CDC_SET CDC where CDC.CDC_SET_NAME = 'FUSION.FUSIONTABLEUPDATEDEMO' """ selCmd = """ select count('X') from FUSION.SNP_CDC_SUBS CDC where CDC.CDC_SET_NAME = 'FUSION.FUSIONTABLEUPDATEDEMO' and CDC.CDC_SUBSCRIBER = ? """ # Prepare the statements prepInsStmt = myCon.prepareStatement(insCmd) prepSelStmt = myCon.prepareStatement(selCmd) # Execute for each subscriber for sbs in lstSbs: prepSelStmt.setString(1, sbs) rs = prepSelStmt.executeQuery() rs.next() nbSubs = rs.getInt(1) if (nbSubs == 0): prepInsStmt.setString(1, sbs) nbRows = prepInsStmt.executeUpdate() prepInsStmt.close() prepSelStmt.close() # Commit the updates myCon.commit()
13. Update SNP_CDC_SUBS
updCmd = """ update FUSION.SNP_CDC_SUBS SUBS set ( SUBS.MAX_WINDOW_ID, SUBS.MAX_WINDOW_ID_INS, SUBS.MAX_WINDOW_ID_DEL ) = ( select CDC.CUR_WINDOW_ID, CDC.CUR_WINDOW_ID_INS, CDC.CUR_WINDOW_ID_DEL from FUSION.SNP_CDC_SET CDC where CDC.CDC_SET_NAME = 'FUSION.FUSIONTABLEUPDATEDEMO' ) where SUBS.CDC_SET_NAME = 'FUSION.FUSIONTABLEUPDATEDEMO' and SUBS.CDC_SUBSCRIBER = ? """ # Prepare the update prepUpdStmt = myCon.prepareStatement(updCmd) # Execute it for each subscriber for sbs in lstSbs: prepUpdStmt.setString(1, sbs) nbRows = prepUpdStmt.executeUpdate() prepUpdStmt.close() # Commit the updates myCon.commit()
14. Update SNP_CDC_SUBS
updCmd = """ update FUSION.SNP_CDC_SUBS SUBS set SUBS.MIN_WINDOW_ID = SUBS.MAX_WINDOW_ID_INS where SUBS.CDC_SET_NAME = 'FUSION.FUSIONTABLEUPDATEDEMO' and SUBS.CDC_SUBSCRIBER = ? """ # Prepare the update prepUpdStmt = myCon.prepareStatement(updCmd) # Execute it for each subscriber for sbs in lstSbs: prepUpdStmt.setString(1, sbs) nbRows = prepUpdStmt.executeUpdate() prepUpdStmt.close() # Commit the updates myCon.commit()
15.
/* After each change on the content of this table we recompute the statistics */ /* Statistics are always up to date on this table */ begin dbms_stats.gather_table_stats( ownname => 'FUSION', tabname => 'SNP_CDC_SUBS', estimate_percent => dbms_stats.auto_sample_size ); end;
16. Close the connection
myCon.close()
Open diary
1. Check the database version
DECLARE -- Validating KM options dbVersion1 NUMBER(2,0); dbVersion2 NUMBER(2,0); BEGIN -- Verify RDBMS version select case when upper(name) = 'COMPATIBLE' then to_number(substr(value, 1, instr(value, '.',1,1)-1)) else null end v0, case when upper(name) = 'COMPATIBLE' then to_number(substr(value, instr(value, '.',1,1)+1, instr(value, '.',1,2)-instr(value, '.',1,1)-1)) else null end v1 into dbVersion1, dbVersion2 from v$parameter where upper(name) = 'COMPATIBLE'; IF dbVersion1 < 9 THEN raise_application_error(-20101, 'ODIKM-ORA-10000: You are using RDBMS version '||dbVersion1||'.'||dbVersion2||'. This version does not support JKM COMPATIBLE= 9.'); END IF; END;
2. Open the connection
import java.sql as sql import java.lang as lang # Connect to the Source Database ie the one that hosts the journalized tables myCon = odiRef.getJDBCConnection("SRC") # Create the list of Subscribers for a CDC Set lstSbs = []
3. Create table SNP_CDC_SUBS
/* This table is created in the work physical schema set as default for the Data server */ create table FUSION.SNP_CDC_SUBS ( CDC_SET_NAME VARCHAR2(255 CHAR) not null, /* Name of the CDC Set (ODI model code following the Local Mask syntax) */ CDC_SUBSCRIBER VARCHAR2(400 CHAR) not null, /* Name of the subscriber who subscribed to the CDC Set */ CDC_REFDATE DATE not null, /* Last update of the record */ MIN_WINDOW_ID NUMBER(20) not null, /* Window Ids under this one should be ignored */ MAX_WINDOW_ID NUMBER(20) not null, /* Maximum Window Id used by this subscription */ MAX_WINDOW_ID_DEL NUMBER(20) not null, /* Maximum Window Id to take into consideration when looking at consistency for deletes */ MAX_WINDOW_ID_INS NUMBER(20) not null, /* Maximum Window Id to take into consideration when looking at consistency for inserts / updates */ CDC_ROW_COUNT NUMBER(10) not null, /* Number of rows in the journalizing tables for this subscription */ constraint PK_SNP_CDC_SBS primary key (CDC_SET_NAME, CDC_SUBSCRIBER) )
4. Set the length of the SNP_CDC_SUBS field CDC_SUBSCRIBER
alter table FUSION.SNP_CDC_SUBS modify (CDC_SUBSCRIBER VARCHAR2(400 CHAR))
5. Set the length of the SNP_CDC_SUBS_AE field CDC_SUBSCRIBER
alter table FUSION.SNP_CDC_SUBS_AE modify (CDC_SUBSCRIBER VARCHAR2(400 CHAR))
6. Create table SNP_CDC_SET
/* This table is created in the work physical schema set as default for the Data server */ create table FUSION.SNP_CDC_SET ( CDC_SET_NAME VARCHAR2(255 CHAR) not null, /* Name of the CDC Set (ODI model code following the Local Mask syntax) */ CUR_WINDOW_ID NUMBER(20) not null, /* Last window Id that has been used */ CUR_WINDOW_ID_DEL NUMBER(20) not null, /* Last Window Id used to compute delete consitency */ CUR_WINDOW_ID_INS NUMBER(20) not null, /* Last Window Id used to compute inert / update consitency */ RETRIEVE_DATA VARCHAR2(2000 CHAR) null, /* Command to execute in order to retrieve the journal data (used by the OdiRetrieveJournalData tool) */ REFRESH_ROW_COUNT VARCHAR2(2000 CHAR) null, /* Command to execute in order to refresh the row count(used by the OdiRefreshJournalData tool) */ constraint PK_SNP_CDC_SET primary key (CDC_SET_NAME) )
7. Create table SNP_CDC_SET_TABLE
/* This table is created in the work physical schema set as default for the Data server */ create table FUSION.SNP_CDC_SET_TABLE ( CDC_SET_NAME VARCHAR2(255 CHAR) not null, /* Name of the CDC Set (ODI model code following the Local Mask syntax) */ FULL_TABLE_NAME VARCHAR2(255 CHAR) not null, /* Complete name of the journalized table */ FULL_DATA_VIEW VARCHAR2(255 CHAR) not null, /* Complete name of the journalizing data view */ RETRIEVE_DATA VARCHAR2(2000 CHAR) null, /* Command to execute to retrieve the journal data (used by the OdiRetrieveJournalData tool) */ REFRESH_ROW_COUNT VARCHAR2(2000 CHAR) null, /* Command to execute to refresh the row count (used by the OdiRefreshRowCount tool) */ CDC_LAST_DATE TIMESTAMP, CDC_CURRENT_DATE TIMESTAMP, constraint PK_SNP_CDC_TBL primary key (FULL_TABLE_NAME) )
8.SNP_CDC_SET_TABLE Add Fields
alter table FUSION.SNP_CDC_SET_TABLE add ( CDC_LAST_DATE TIMESTAMP, CDC_CURRENT_DATE TIMESTAMP )
9. Building table SNP_CDC_OBJECTS
/* This table is created in the work physical schema set as default for the Data server */ create table FUSION.SNP_CDC_OBJECTS ( FULL_TABLE_NAME VARCHAR2(255 CHAR) not null, /* Complete name of the journalized table */ CDC_OBJECT_TYPE VARCHAR2(35 CHAR) not null, /* Type of the object in the CDC framework */ FULL_OBJECT_NAME VARCHAR2(255 CHAR) not null, /* Complete name of the object */ DB_OBJECT_TYPE VARCHAR2(35 CHAR) null, /* RDBMS type of the object (ex : TABLE, VIEW, TRIGGER) */ constraint PK_SNP_CDC_OBJ primary key (FULL_TABLE_NAME, CDC_OBJECT_TYPE) )
10. Insert data into SNP_CDC_SET
insert into FUSION.SNP_CDC_SET ( CDC_SET_NAME, CUR_WINDOW_ID, CUR_WINDOW_ID_DEL, CUR_WINDOW_ID_INS, RETRIEVE_DATA, REFRESH_ROW_COUNT ) values ( /* CDC_SET_NAME */ 'FUSION.FUSIONTABLEUPDATEDEMO', /* CUR_WINDOW_ID */ -1, /* CUR_WINDOW_ID_DEL */ -1, /* CUR_WINDOW_ID_INS */ -1, /* RETRIEVE_DATA */ NULL, /* REFRESH_ROW_COUNT */ 'update FUSION.SNP_CDC_SUBS set CDC_ROW_COUNT = 0 ' || 'where CDC_SUBSCRIBER = ''$$SUBSCRIBER_NAME$$'' ' || 'and CDC_SET_NAME = ''FUSION.FUSIONTABLEUPDATEDEMO'' ' )
11. Update SNP_CDC_SET
update FUSION.SNP_CDC_SET CDC set CDC.RETRIEVE_DATA = NULL, CDC.REFRESH_ROW_COUNT = 'update FUSION.SNP_CDC_SUBS set CDC_ROW_COUNT = 0 ' || 'where CDC_SUBSCRIBER = ''$$SUBSCRIBER_NAME$$'' ' || 'and CDC_SET_NAME = ''FUSION.FUSIONTABLEUPDATEDEMO'' ' where CDC.CDC_SET_NAME = 'FUSION.FUSIONTABLEUPDATEDEMO'
12. Delete SNP_TMP_TABLE_LIST
drop table FUSION.SNP_TMP_TABLE_LIST
13. Create table SNP_TMP_TABLE_LIST
create table FUSION.SNP_TMP_TABLE_LIST ( FULL_TABLE_NAME VARCHAR2(255 CHAR) not null )
14. Insert data into table SNP_TMP_TABLE_LIST, the data content is the table adding diary.
insert into FUSION.SNP_TMP_TABLE_LIST ( FULL_TABLE_NAME ) values ( /* FULL_TABLE_NAME */ 'FUSION.DMS_TEST_DELET_SOURCE' )
15. Create log tables
/* This command is sent to the database only if the table is not already a part of the set */ /* If you want this command to be always executed, remove the query on the source tab */ create table FUSION.J$DMS_TEST_DELET_SOURCE /* This table is created in the work physical schema of the current Data server */ ( WINDOW_ID NUMBER(20) null, ID NUMBER null )
16. Insert data into SNP_CDC_OBJECTS to add diary tables and generated tables
insert into FUSION.SNP_CDC_OBJECTS ( FULL_TABLE_NAME, CDC_OBJECT_TYPE, FULL_OBJECT_NAME, DB_OBJECT_TYPE ) values ( /* FULL_TABLE_NAME */ 'FUSION.DMS_TEST_DELET_SOURCE', /* CDC_OBJECT_TYPE */ 'JRN_FULL_NAME', /* FULL_OBJECT_NAME */ 'FUSION.J$DMS_TEST_DELET_SOURCE', /* DB_OBJECT_TYPE */ 'TABLE' )
17. Create view JV$DMS_TEST_DELET_SOURCE
create or replace view FUSION.JV$DMS_TEST_DELET_SOURCE /* This view is created in the work physical schema of the current Data server */ as select decode(TARG.ROWID, null, 'D', 'I') AS JRN_FLAG, sysdate AS JRN_DATE, /* For V3 compatibility */ JRN.CDC_SUBSCRIBER AS JRN_SUBSCRIBER, /* Renamed for V3 compatibility */ JRN.ID AS ID ,TARG.HOST AS HOST, TARG.PORT AS PORT, TARG.NAME AS NAME, TARG.APPLICATION AS APPLICATION, TARG.CONTEXT_ROOT AS CONTEXT_ROOT, TARG.SERVICE AS SERVICE, TARG.PATH AS PATH, TARG.DEPLOYMENT_STATE AS DEPLOYMENT_STATE, TARG.SOURCE_INFORMATION AS SOURCE_INFORMATION, TARG.ACTIVE_SERVER_COUNT AS ACTIVE_SERVER_COUNT, TARG.SERVLETS AS SERVLETS, TARG.PENDING_REQUESTS AS PENDING_REQUESTS, TARG.COMPLETED_REQUESTS AS COMPLETED_REQUESTS, TARG.OPEN_SESSIONS_CURRENT_COUNT AS OPEN_SESSIONS_CURRENT_COUNT, TARG.OPEN_SESSIONS_HIGH_COUNT AS OPEN_SESSIONS_HIGH_COUNT, TARG.SESSIONS_OPENED_TOTAL_COUNT AS SESSIONS_OPENED_TOTAL_COUNT, TARG.OBJECT_VERSION_NUMBER AS OBJECT_VERSION_NUMBER, TARG.CREATION_DATE AS CREATION_DATE, TARG.CREATED_BY AS CREATED_BY, TARG.LAST_UPDATE_DATE AS LAST_UPDATE_DATE, TARG.LAST_UPDATED_BY AS LAST_UPDATED_BY, TARG.DATA_STATUS AS DATA_STATUS from (select JRN.ID,SUB.CDC_SUBSCRIBER, SUB.MAX_WINDOW_ID_INS, max(JRN.WINDOW_ID) WINDOW_ID from FUSION.J$DMS_TEST_DELET_SOURCE JRN, FUSION.SNP_CDC_SUBS SUB where SUB.CDC_SET_NAME = 'FUSION.FUSIONTABLEUPDATEDEMO' and JRN.WINDOW_ID > SUB.MIN_WINDOW_ID and JRN.WINDOW_ID <= SUB.MAX_WINDOW_ID_DEL group by JRN.ID,SUB.CDC_SUBSCRIBER, SUB.MAX_WINDOW_ID_INS) JRN, FUSION.DMS_TEST_DELET_SOURCE TARG where JRN.ID = TARG.ID (+) and not ( TARG.ROWID is not null and JRN.WINDOW_ID > JRN.MAX_WINDOW_ID_INS ) select JRN.ID,SUB.CDC_SUBSCRIBER, SUB.MAX_WINDOW_ID_INS, max(JRN.WINDOW_ID) WINDOW_ID from FUSION.J$DMS_TEST_DELET_SOURCE JRN, FUSION.SNP_CDC_SUBS SUB where SUB.CDC_SET_NAME = 'FUSION.FUSIONTABLEUPDATEDEMO' and JRN.WINDOW_ID > SUB.MIN_WINDOW_ID and JRN.WINDOW_ID <= SUB.MAX_WINDOW_ID_DEL group by JRN.ID,SUB.CDC_SUBSCRIBER, SUB.MAX_WINDOW_ID_INS
18. Insert data into the SNP_CDC_OBJECTS table to add diaries and new views
insert into FUSION.SNP_CDC_OBJECTS ( FULL_TABLE_NAME, CDC_OBJECT_TYPE, FULL_OBJECT_NAME, DB_OBJECT_TYPE ) values ( /* FULL_TABLE_NAME */ 'FUSION.DMS_TEST_DELET_SOURCE', /* CDC_OBJECT_TYPE */ 'JRN_FULL_VIEW', /* FULL_OBJECT_NAME */ 'FUSION.JV$DMS_TEST_DELET_SOURCE', /* DB_OBJECT_TYPE */ 'VIEW' )
19. Create view DDMS_TEST_DELET_SOURCE
create or replace view FUSION.JV$DDMS_TEST_DELET_SOURCE /* This view is created in the work physical schema of the current Data server */ as select decode(TARG.ROWID, null, 'D', 'I') AS JRN_FLAG, sysdate AS JRN_DATE, /* For V3 compatibility */ SUB.CDC_SUBSCRIBER AS JRN_SUBSCRIBER, /* Renamed for V3 compatibility */ PKS.ID AS ID ,TARG.HOST AS HOST, TARG.PORT AS PORT, TARG.NAME AS NAME, TARG.APPLICATION AS APPLICATION, TARG.CONTEXT_ROOT AS CONTEXT_ROOT, TARG.SERVICE AS SERVICE, TARG.PATH AS PATH, TARG.DEPLOYMENT_STATE AS DEPLOYMENT_STATE, TARG.SOURCE_INFORMATION AS SOURCE_INFORMATION, TARG.ACTIVE_SERVER_COUNT AS ACTIVE_SERVER_COUNT, TARG.SERVLETS AS SERVLETS, TARG.PENDING_REQUESTS AS PENDING_REQUESTS, TARG.COMPLETED_REQUESTS AS COMPLETED_REQUESTS, TARG.OPEN_SESSIONS_CURRENT_COUNT AS OPEN_SESSIONS_CURRENT_COUNT, TARG.OPEN_SESSIONS_HIGH_COUNT AS OPEN_SESSIONS_HIGH_COUNT, TARG.SESSIONS_OPENED_TOTAL_COUNT AS SESSIONS_OPENED_TOTAL_COUNT, TARG.OBJECT_VERSION_NUMBER AS OBJECT_VERSION_NUMBER, TARG.CREATION_DATE AS CREATION_DATE, TARG.CREATED_BY AS CREATED_BY, TARG.LAST_UPDATE_DATE AS LAST_UPDATE_DATE, TARG.LAST_UPDATED_BY AS LAST_UPDATED_BY, TARG.DATA_STATUS AS DATA_STATUS from ( select distinct PKS_UNION.ID,PKS_UNION.WINDOW_ID from ( select JRN.ID,JRN.WINDOW_ID from FUSION.J$DMS_TEST_DELET_SOURCE JRN union select TARG.ID,null from FUSION.DMS_TEST_DELET_SOURCE TARG, FUSION.SNP_CDC_SET_TABLE CDCTAB where TARG.LAST_UPDATE_DATE >= CDCTAB.CDC_LAST_DATE and CDCTAB.CDC_SET_NAME = 'FUSION.FUSIONTABLEUPDATEDEMO' and CDCTAB.FULL_TABLE_NAME = 'FUSION.DMS_TEST_DELET_SOURCE' ) PKS_UNION ) PKS, FUSION.SNP_CDC_SUBS SUB, FUSION.DMS_TEST_DELET_SOURCE TARG where PKS.ID = TARG.ID (+) and SUB.CDC_SET_NAME = 'FUSION.FUSIONTABLEUPDATEDEMO' and (PKS.WINDOW_ID > SUB.MIN_WINDOW_ID or PKS.WINDOW_ID is null)
20. Insert data into SNP_CDC_OBJECTS, which are tables with added diaries and JV$DDMS_TEST_DELET_SOURCE
insert into FUSION.SNP_CDC_OBJECTS ( FULL_TABLE_NAME, CDC_OBJECT_TYPE, FULL_OBJECT_NAME, DB_OBJECT_TYPE ) values ( /* FULL_TABLE_NAME */ 'FUSION.DMS_TEST_DELET_SOURCE', /* CDC_OBJECT_TYPE */ 'JRN_FULL_DATA_VIEW', /* FULL_OBJECT_NAME */ 'FUSION.JV$DDMS_TEST_DELET_SOURCE', /* DB_OBJECT_TYPE */ 'VIEW' )
21. Create and delete Trigger
triggerCmd = """ create or replace trigger FUSION.T$DMS_TEST_DELET_SOURCE after delete on FUSION.DMS_TEST_DELET_SOURCE for each row declare V_ID NUMBER; begin V_ID := :old.ID; insert into FUSION.J$DMS_TEST_DELET_SOURCE ( WINDOW_ID, ID ) values ( /* WINDOW_ID */ NULL, :old.ID ); end; """ # Create the statement myStmt = myCon.createStatement() # Execute the trigger creation myStmt.execute(triggerCmd) myStmt.close() myStmt = None # Commit, just in case myCon.commit()
22. Insert data into the table SNP_CDC_OBJECTS with the contents of the tables with diaries and T$DMS_TEST_DELET_SOURCE
insert into FUSION.SNP_CDC_OBJECTS ( FULL_TABLE_NAME, CDC_OBJECT_TYPE, FULL_OBJECT_NAME, DB_OBJECT_TYPE ) values ( /* FULL_TABLE_NAME */ 'FUSION.DMS_TEST_DELET_SOURCE', /* CDC_OBJECT_TYPE */ 'JRN_FULL_TRIGGER', /* FULL_OBJECT_NAME */ 'FUSION.T$DMS_TEST_DELET_SOURCE', /* DB_OBJECT_TYPE */ 'TRIGGER' )
23. Delete FUSION. FUSION TABLEUPDATEDEMO in SNP_CDC_SET_TABLE
delete from FUSION.SNP_CDC_SET_TABLE CDC where CDC.CDC_SET_NAME = 'FUSION.FUSIONTABLEUPDATEDEMO' and CDC.FULL_TABLE_NAME = 'FUSION.DMS_TEST_DELET_SOURCE'
24. Insert data into SNP_CDC_SET_TABLE
insert into FUSION.SNP_CDC_SET_TABLE ( CDC_SET_NAME, FULL_TABLE_NAME, FULL_DATA_VIEW, RETRIEVE_DATA, REFRESH_ROW_COUNT, CDC_LAST_DATE, CDC_CURRENT_DATE ) values ( /* CDC_SET_NAME */ 'FUSION.FUSIONTABLEUPDATEDEMO', /* FULL_TABLE_NAME */ 'FUSION.DMS_TEST_DELET_SOURCE', /* FULL_DATA_VIEW */ 'FUSION.JV$DDMS_TEST_DELET_SOURCE', /* RETRIEVE_DATA */ NULL, /* REFRESH_ROW_COUNT */ 'update FUSION.SNP_CDC_SUBS SUBS set SUBS.CDC_ROW_COUNT = (select SUBS.CDC_ROW_COUNT + count(*) from FUSION.JV$DDMS_TEST_DELET_SOURCE where JRN_SUBSCRIBER = ''$$SUBSCRIBER_NAME$$'') where CDC_SET_NAME = ''FUSION.FUSIONTABLEUPDATEDEMO'' and CDC_SUBSCRIBER=''$$SUBSCRIBER_NAME$$''', sysdate, sysdate )
25. Delete the temporary table SNP_TMP_TABLE_LIST
drop table FUSION.SNP_TMP_TABLE_LIST
26. Locking CDC records
/* Mandatory to prevent OdiRetrieveData or other Extend window in parallel */ update FUSION.SNP_CDC_SET CDC set CDC.CUR_WINDOW_ID = CDC.CUR_WINDOW_ID + 2, CDC.CUR_WINDOW_ID_INS = CDC.CUR_WINDOW_ID + 1, CDC.CUR_WINDOW_ID_DEL = CDC.CUR_WINDOW_ID + 2 where CDC.CDC_SET_NAME = 'FUSION.FUSIONTABLEUPDATEDEMO'
27. Set up CDC Current Date
update FUSION.SNP_CDC_SET_TABLE set CDC_CURRENT_DATE = ( select nvl(min(SCN_TO_TIMESTAMP(TR.start_scnb)),SYSTIMESTAMP-6/86400) cur_time from gv$transaction TR, gv$session SE, gv$lock LK, all_objects OB where TR.addr = SE.taddr and SE.sid = LK.sid and LK.id1 = OB.object_id and OB.owner || '.' || OB.object_name = 'FUSION.DMS_TEST_DELET_SOURCE' ) where CDC_SET_NAME = 'FUSION.FUSIONTABLEUPDATEDEMO' and FULL_TABLE_NAME = 'FUSION.DMS_TEST_DELET_SOURCE'
28. Insert data into the J$DMS_TEST_DELET_SOURCE table
/* Compute Window Id for each table of the CDC Set from children to parents */ /* This computes consistency regarding Inserts and Updates */ /* Since there are no triggers, the J$ table is populated by the extend window step... */ insert into FUSION.J$DMS_TEST_DELET_SOURCE ( WINDOW_ID, ID ) select /* WINDOW_ID */ CDCSET.CUR_WINDOW_ID + 1, TARG.ID from FUSION.DMS_TEST_DELET_SOURCE TARG, ( -- Get current window id select CUR_WINDOW_ID from FUSION.SNP_CDC_SET where CDC_SET_NAME = 'FUSION.FUSIONTABLEUPDATEDEMO' ) CDCSET, FUSION.SNP_CDC_SET_TABLE CDCTAB where TARG.LAST_UPDATE_DATE >= CDCTAB.CDC_LAST_DATE and CDCTAB.CDC_SET_NAME = 'FUSION.FUSIONTABLEUPDATEDEMO' and CDCTAB.FULL_TABLE_NAME = 'FUSION.DMS_TEST_DELET_SOURCE'
29. Update FUSION.SNP_CDC_SET_TABLE
update FUSION.SNP_CDC_SET_TABLE set CDC_LAST_DATE = CDC_CURRENT_DATE where CDC_SET_NAME = 'FUSION.FUSIONTABLEUPDATEDEMO' and FULL_TABLE_NAME = 'FUSION.DMS_TEST_DELET_SOURCE'
30. unlock CDC
/* commit */
31.
/* After each change on the content of this table we recompute the statistics */ /* Statistics are always up to date on this table */ begin dbms_stats.gather_table_stats( ownname => 'FUSION', tabname => 'SNP_CDC_SET_TABLE', estimate_percent => dbms_stats.auto_sample_size ); end;
32. Close the connection
myCon.close()
Extension window
1. Verification Version
DECLARE -- Validating KM options dbVersion1 NUMBER(2,0); dbVersion2 NUMBER(2,0); BEGIN -- Verify RDBMS version select case when upper(name) = 'COMPATIBLE' then to_number(substr(value, 1, instr(value, '.',1,1)-1)) else null end v0, case when upper(name) = 'COMPATIBLE' then to_number(substr(value, instr(value, '.',1,1)+1, instr(value, '.',1,2)-instr(value, '.',1,1)-1)) else null end v1 into dbVersion1, dbVersion2 from v$parameter where upper(name) = 'COMPATIBLE'; IF dbVersion1 < 9 THEN raise_application_error(-20101, 'ODIKM-ORA-10000: You are using RDBMS version '||dbVersion1||'.'||dbVersion2||'. This version does not support JKM COMPATIBLE= 9.'); END IF; END;
2. Update CDC data
/* Mandatory to prevent OdiRetrieveData or other Extend window in parallel */ update FUSION.SNP_CDC_SET CDC set CDC.CUR_WINDOW_ID = CDC.CUR_WINDOW_ID + 2, CDC.CUR_WINDOW_ID_INS = CDC.CUR_WINDOW_ID + 1, CDC.CUR_WINDOW_ID_DEL = CDC.CUR_WINDOW_ID + 2 where CDC.CDC_SET_NAME = 'FUSION.FUSIONTABLEUPDATEDEMO'
3. Update SNP? CDC? Set? Table data
update FUSION.SNP_CDC_SET_TABLE data set CDC_CURRENT_DATE = ( select nvl(min(SCN_TO_TIMESTAMP(TR.start_scnb)),SYSTIMESTAMP-6/86400) cur_time from gv$transaction TR, gv$session SE, gv$lock LK, all_objects OB where TR.addr = SE.taddr and SE.sid = LK.sid and LK.id1 = OB.object_id and OB.owner || '.' || OB.object_name = 'FUSION.DMS_TEST_DELET_SOURCE' ) where CDC_SET_NAME = 'FUSION.FUSIONTABLEUPDATEDEMO' and FULL_TABLE_NAME = 'FUSION.DMS_TEST_DELET_SOURCE'
4. Insert data into the FUSION.J$DMS_TEST_DELET_SOURCE table
/* Compute Window Id for each table of the CDC Set from children to parents */ /* This computes consistency regarding Inserts and Updates */ /* Since there are no triggers, the J$ table is populated by the extend window step... */ insert into FUSION.J$DMS_TEST_DELET_SOURCE ( WINDOW_ID, ID ) select /* WINDOW_ID */ CDCSET.CUR_WINDOW_ID + 1, TARG.ID from FUSION.DMS_TEST_DELET_SOURCE TARG, ( -- Get current window id select CUR_WINDOW_ID from FUSION.SNP_CDC_SET where CDC_SET_NAME = 'FUSION.FUSIONTABLEUPDATEDEMO' ) CDCSET, FUSION.SNP_CDC_SET_TABLE CDCTAB where TARG.LAST_UPDATE_DATE >= CDCTAB.CDC_LAST_DATE and CDCTAB.CDC_SET_NAME = 'FUSION.FUSIONTABLEUPDATEDEMO' and CDCTAB.FULL_TABLE_NAME = 'FUSION.DMS_TEST_DELET_SOURCE'
5. Update J$DMS_TEST_DELET_SOURCE
/* Compute Window Id for each table of the CDC Set from parents to children */ /* This computes consistency regarding Deletes */ update FUSION.J$DMS_TEST_DELET_SOURCE JRN set JRN.WINDOW_ID = ( select CDC.CUR_WINDOW_ID_DEL + 2 from FUSION.SNP_CDC_SET CDC where CDC.CDC_SET_NAME = 'FUSION.FUSIONTABLEUPDATEDEMO' ) where JRN.WINDOW_ID is null
6. Update the last update time of CDC in the SNP_CDC_SET_TABLE table
update FUSION.SNP_CDC_SET_TABLE set CDC_LAST_DATE = CDC_CURRENT_DATE where CDC_SET_NAME = 'FUSION.FUSIONTABLEUPDATEDEMO' and FULL_TABLE_NAME = 'FUSION.DMS_TEST_DELET_SOURCE'
7. unlock CDC
/* commit */
8.
begin dbms_stats.gather_table_stats( ownname => 'FUSION', tabname => 'J$DMS_TEST_DELET_SOURCE', estimate_percent => dbms_stats.auto_sample_size ); end;
9.
myCon.close()
Execute the following code
update FUSION.SNP_CDC_SET CDC set CDC.CUR_WINDOW_ID = CDC.CUR_WINDOW_ID + 2, CDC.CUR_WINDOW_ID_INS = CDC.CUR_WINDOW_ID + 1, CDC.CUR_WINDOW_ID_DEL = CDC.CUR_WINDOW_ID + 2 where CDC.CDC_SET_NAME = 'FUSION.FUSIONTABLEUPDATEDEMO'
Update fields in FUSION.SNP_CDC_SET
Update FUSION.SNP_CDC_SET_TABLE to set CDC_CURRENT_DATE to the current time
Insert data into the FUSION.J $DMS_TEST_DELET_SOURURCE table with the value FUSION.FUSION.SNP_CDC_SET taken from FUSION.SNP_CDC_SET.FUSIONTABLEUPDATEDEMO data CDCSET.CUR_WINDOW_ID+1, provided that the last update time of TARG.LAST_UPDATE_DATE (target table) was later than the last operation time of FUSION.SNP_CDC DC DC_SET_BLELELELELEG. LAST_DADADADATETETE_DADADATE_BLELELELELELEG. DADADADADADADADADADADADADATETE_DATETETE_DADADADADAUpdate to The current time is then updated each time the window is expanded, after inserting data into the FUSION.J$DMS_TEST_DELET_SOURCE table
This means that if the last update time is earlier than the last operation time of the CDC, the record will not be captured.
insert into FUSION.J$DMS_TEST_DELET_SOURCE ( WINDOW_ID, ID ) select /* WINDOW_ID */ CDCSET.CUR_WINDOW_ID + 1, TARG.ID from FUSION.DMS_TEST_DELET_SOURCE TARG, ( -- Get current window id select CUR_WINDOW_ID from FUSION.SNP_CDC_SET where CDC_SET_NAME = 'FUSION.FUSIONTABLEUPDATEDEMO' ) CDCSET, FUSION.SNP_CDC_SET_TABLE CDCTAB where TARG.LAST_UPDATE_DATE >= CDCTAB.CDC_LAST_DATE and CDCTAB.CDC_SET_NAME = 'FUSION.FUSIONTABLEUPDATEDEMO' and CDCTAB.FULL_TABLE_NAME = 'FUSION.DMS_TEST_DELET_SOURCE'
Update FUSION.J$DMS_TEST_DELET_SOURCE to set WINDOW_ID without JRN.WINDOW_ID
/* Compute Window Id for each table of the CDC Set from parents to children */ /* This computes consistency regarding Deletes */ update FUSION.J$DMS_TEST_DELET_SOURCE JRN set JRN.WINDOW_ID = ( select CDC.CUR_WINDOW_ID_DEL + 2 from FUSION.SNP_CDC_SET CDC where CDC.CDC_SET_NAME = 'FUSION.FUSIONTABLEUPDATEDEMO' ) where JRN.WINDOW_ID is null
Set CDC_LAST_DATE to CDC_CURRENT_DATE and update CDC_LAST_DATE mentioned above
update FUSION.SNP_CDC_SET_TABLE set CDC_LAST_DATE by = CDC_CURRENT_DATE where CDC_SET_NAME = 'FUSION.FUSIONTABLEUPDATEDEMO' and FULL_TABLE_NAME = 'FUSION.DMS_TEST_DELET_SOURCE'
Lock subscriber
1. Verification Version
DECLARE -- Validating KM options dbVersion1 NUMBER(2,0); dbVersion2 NUMBER(2,0); BEGIN -- Verify RDBMS version select case when upper(name) = 'COMPATIBLE' then to_number(substr(value, 1, instr(value, '.',1,1)-1)) else null end v0, case when upper(name) = 'COMPATIBLE' then to_number(substr(value, instr(value, '.',1,1)+1, instr(value, '.',1,2)-instr(value, '.',1,1)-1)) else null end v1 into dbVersion1, dbVersion2 from v$parameter where upper(name) = 'COMPATIBLE'; IF dbVersion1 < 9 THEN raise_application_error(-20101, 'ODIKM-ORA-10000: You are using RDBMS version '||dbVersion1||'.'||dbVersion2||'. This version does not support JKM COMPATIBLE= 9.'); END IF; END;
2. Getting Connections
import java.sql as sql import java.lang as lang # Connect to the Source Database ie the one that hosts the journalized tables myCon = odiRef.getJDBCConnection("SRC") # Create the list of Subscribers for a CDC Set lstSbs = [] lstSbs.append('Zero')
3.
updCmd = """ update FUSION.SNP_CDC_SUBS SUBS set ( SUBS.MAX_WINDOW_ID, SUBS.MAX_WINDOW_ID_INS, SUBS.MAX_WINDOW_ID_DEL ) = ( select CDC.CUR_WINDOW_ID, CDC.CUR_WINDOW_ID_INS, CDC.CUR_WINDOW_ID_DEL from FUSION.SNP_CDC_SET CDC where CDC.CDC_SET_NAME = 'FUSION.FUSIONTABLEUPDATEDEMO' ) where SUBS.CDC_SET_NAME = 'FUSION.FUSIONTABLEUPDATEDEMO' and SUBS.CDC_SUBSCRIBER = ? """ # Prepare the update prepUpdStmt = myCon.prepareStatement(updCmd) # Execute it for each subscriber for sbs in lstSbs: prepUpdStmt.setString(1, sbs) nbRows = prepUpdStmt.executeUpdate() prepUpdStmt.close() # Commit the updates myCon.commit()
4. Close the connection
myCon.close()
updCmd = """
update FUSION.SNP_CDC_SUBS SUBS set ( SUBS.MAX_WINDOW_ID, SUBS.MAX_WINDOW_ID_INS, SUBS.MAX_WINDOW_ID_DEL ) = ( select CDC.CUR_WINDOW_ID, CDC.CUR_WINDOW_ID_INS, CDC.CUR_WINDOW_ID_DEL from FUSION.SNP_CDC_SET CDC where CDC.CDC_SET_NAME = 'FUSION.FUSIONTABLEUPDATEDEMO' ) where SUBS.CDC_SET_NAME = 'FUSION.FUSIONTABLEUPDATEDEMO' and SUBS.CDC_SUBSCRIBER = ? """
//Prepare the update
prepUpdStmt = myCon.prepareStatement(updCmd)
//Execute it for each subscriber
for sbs in lstSbs://traverse the list of listeners and update all listeners
prepUpdStmt.setString(1, sbs)//Setting placeholders nbRows = prepUpdStmt.executeUpdate()//Perform update operations
prepUpdStmt.close()
// Commit the updates
myCon.commit()
Update the FUSION.SNP_CDC_SUBS parameter and set the FUSION.SNP_CDC_SET CUR parameter to FUSION.SNP_CDC_SUBS MAX parameter.
select
decode(TARG.ROWID, null, 'D', 'I') AS JRN_FLAG, sysdate AS JRN_DATE, JRN.CDC_SUBSCRIBER AS JRN_SUBSCRIBER, JRN.ID AS ID ,TARG.HOST AS HOST, TARG.PORT AS PORT, TARG.NAME AS NAME, TARG.APPLICATION AS APPLICATION, TARG.CONTEXT_ROOT AS CONTEXT_ROOT, TARG.SERVICE AS SERVICE, TARG.PATH AS PATH, TARG.DEPLOYMENT_STATE AS DEPLOYMENT_STATE, TARG.SOURCE_INFORMATION AS SOURCE_INFORMATION, TARG.ACTIVE_SERVER_COUNT AS ACTIVE_SERVER_COUNT, TARG.SERVLETS AS SERVLETS, TARG.PENDING_REQUESTS AS PENDING_REQUESTS, TARG.COMPLETED_REQUESTS AS COMPLETED_REQUESTS, TARG.OPEN_SESSIONS_CURRENT_COUNT AS OPEN_SESSIONS_CURRENT_COUNT, TARG.OPEN_SESSIONS_HIGH_COUNT AS OPEN_SESSIONS_HIGH_COUNT, TARG.SESSIONS_OPENED_TOTAL_COUNT AS SESSIONS_OPENED_TOTAL_COUNT, TARG.OBJECT_VERSION_NUMBER AS OBJECT_VERSION_NUMBER, TARG.CREATION_DATE AS CREATION_DATE, TARG.CREATED_BY AS CREATED_BY, TARG.LAST_UPDATE_DATE AS LAST_UPDATE_DATE, TARG.LAST_UPDATED_BY AS LAST_UPDATED_BY, TARG.DATA_STATUS AS DATA_STATUS
from (select JRN.ID,SUB.CDC_SUBSCRIBER, SUB.MAX_WINDOW_ID_INS, max(JRN.WINDOW_ID) WINDOW_ID
from FUSION.J$DMS_TEST_DELET_SOURCE JRN, FUSION.SNP_CDC_SUBS SUB where SUB.CDC_SET_NAME = 'FUSION.FUSIONTABLEUPDATEDEMO' and JRN.WINDOW_ID > SUB.MIN_WINDOW_ID and JRN.WINDOW_ID <= SUB.MAX_WINDOW_ID_DEL group by JRN.ID,SUB.CDC_SUBSCRIBER, SUB.MAX_WINDOW_ID_INS) JRN, FUSION.DMS_TEST_DELET_SOURCE TARG
where
JRN.ID = TARG.ID (+) -- Deleted queries in TARG do not appear
and not (
TARG.ROWID is not null--Not delete operation and JRN.WINDOW_ID > JRN.MAX_WINDOW_ID_INS );
TARG.ROWID is null, indicating that the document has been deleted
Execution interface
1. Delete the table FUSION.C$_0SOURCE
drop table FUSION.C$_0SOURCE purge
2. Create the table FUSION.C$_0SOURCE work table
create table FUSION.C$_0SOURCE ( ID NUMBER NULL, HOST VARCHAR2(200) NULL, PORT VARCHAR2(200) NULL, NAME VARCHAR2(200) NULL, APPLICATION VARCHAR2(200) NULL, CONTEXT_ROOT VARCHAR2(200) NULL, SERVICE VARCHAR2(200) NULL, PATH VARCHAR2(4000) NULL, DEPLOYMENT_STATE VARCHAR2(200) NULL, SOURCE_INFORMATION VARCHAR2(200) NULL, ACTIVE_SERVER_COUNT NUMBER NULL, SERVLETS NUMBER NULL, PENDING_REQUESTS NUMBER NULL, COMPLETED_REQUESTS NUMBER NULL, OPEN_SESSIONS_CURRENT_COUNT NUMBER NULL, OPEN_SESSIONS_HIGH_COUNT NUMBER NULL, SESSIONS_OPENED_TOTAL_COUNT NUMBER NULL, OBJECT_VERSION_NUMBER NUMBER NULL, CREATION_DATE DATE NULL, CREATED_BY VARCHAR2(200) NULL, LAST_UPDATE_DATE DATE NULL, LAST_UPDATED_BY VARCHAR2(200) NULL, DATA_STATUS VARCHAR2(200) NULL, JRN_SUBSCRIBER VARCHAR2(50 CHAR) NULL, JRN_FLAG CHAR(1) NULL, JRN_DATE DATE NULL ) NOLOGGING
3. Read data, source execution query fetches data monitored by listeners, target execution insert, and insert data into target table.
Source execution select SOURCE.ID AS ID, SOURCE.HOST AS HOST, SOURCE.PORT AS PORT, SOURCE.NAME AS NAME, SOURCE.APPLICATION AS APPLICATION, SOURCE.CONTEXT_ROOT AS CONTEXT_ROOT, SOURCE.SERVICE AS SERVICE, SOURCE.PATH AS PATH, SOURCE.DEPLOYMENT_STATE AS DEPLOYMENT_STATE, SOURCE.SOURCE_INFORMATION AS SOURCE_INFORMATION, SOURCE.ACTIVE_SERVER_COUNT AS ACTIVE_SERVER_COUNT, SOURCE.SERVLETS AS SERVLETS, SOURCE.PENDING_REQUESTS AS PENDING_REQUESTS, SOURCE.COMPLETED_REQUESTS AS COMPLETED_REQUESTS, SOURCE.OPEN_SESSIONS_CURRENT_COUNT AS OPEN_SESSIONS_CURRENT_COUNT, SOURCE.OPEN_SESSIONS_HIGH_COUNT AS OPEN_SESSIONS_HIGH_COUNT, SOURCE.SESSIONS_OPENED_TOTAL_COUNT AS SESSIONS_OPENED_TOTAL_COUNT, SOURCE.OBJECT_VERSION_NUMBER AS OBJECT_VERSION_NUMBER, SOURCE.CREATION_DATE AS CREATION_DATE, SOURCE.CREATED_BY AS CREATED_BY, SOURCE.LAST_UPDATE_DATE AS LAST_UPDATE_DATE, SOURCE.LAST_UPDATED_BY AS LAST_UPDATED_BY, SOURCE.DATA_STATUS AS DATA_STATUS, JRN_SUBSCRIBER AS JRN_SUBSCRIBER, JRN_FLAG AS JRN_FLAG, JRN_DATE AS JRN_DATE from FUSION.JV$DMS_TEST_DELET_SOURCE SOURCE where (1=1) AND JRN_SUBSCRIBER = 'Zero' /* AND JRN_DATE < sysdate */ //Target execution insert into FUSION.C$_0SOURCE ( ID, HOST, PORT, NAME, APPLICATION, CONTEXT_ROOT, SERVICE, PATH, DEPLOYMENT_STATE, SOURCE_INFORMATION, ACTIVE_SERVER_COUNT, SERVLETS, PENDING_REQUESTS, COMPLETED_REQUESTS, OPEN_SESSIONS_CURRENT_COUNT, OPEN_SESSIONS_HIGH_COUNT, SESSIONS_OPENED_TOTAL_COUNT, OBJECT_VERSION_NUMBER, CREATION_DATE, CREATED_BY, LAST_UPDATE_DATE, LAST_UPDATED_BY, DATA_STATUS, JRN_SUBSCRIBER, JRN_FLAG, JRN_DATE ) values ( :ID, :HOST, :PORT, :NAME, :APPLICATION, :CONTEXT_ROOT, :SERVICE, :PATH, :DEPLOYMENT_STATE, :SOURCE_INFORMATION, :ACTIVE_SERVER_COUNT, :SERVLETS, :PENDING_REQUESTS, :COMPLETED_REQUESTS, :OPEN_SESSIONS_CURRENT_COUNT, :OPEN_SESSIONS_HIGH_COUNT, :SESSIONS_OPENED_TOTAL_COUNT, :OBJECT_VERSION_NUMBER, :CREATION_DATE, :CREATED_BY, :LAST_UPDATE_DATE, :LAST_UPDATED_BY, :DATA_STATUS, :JRN_SUBSCRIBER, :JRN_FLAG, :JRN_DATE )
4.
BEGIN DBMS_STATS.GATHER_TABLE_STATS ( ownname => 'FUSION', tabname => 'C$_0SOURCE', estimate_percent => DBMS_STATS.AUTO_SAMPLE_SIZE ); END;
5. Clean up the diary (what is this operation)
null
6. Delete the table FUSION.I$_DMS_TEST_DELET_TARGET
drop table FUSION.I$_DMS_TEST_DELET_TARGET
7. Create table FUSION.I$_DMS_TEST_DELET_TARGET without log mode
create table FUSION.I$_DMS_TEST_DELET_TARGET ( ID NUMBER NULL, HOST VARCHAR2(200) NULL, PORT VARCHAR2(200) NULL, NAME VARCHAR2(200) NULL, APPLICATION VARCHAR2(200) NULL, CONTEXT_ROOT VARCHAR2(200) NULL, SERVICE VARCHAR2(200) NULL, PATH VARCHAR2(4000) NULL, DEPLOYMENT_STATE VARCHAR2(200) NULL, SOURCE_INFORMATION VARCHAR2(200) NULL, ACTIVE_SERVER_COUNT NUMBER NULL, SERVLETS NUMBER NULL, PENDING_REQUESTS NUMBER NULL, COMPLETED_REQUESTS NUMBER NULL, OPEN_SESSIONS_CURRENT_COUNT NUMBER NULL, OPEN_SESSIONS_HIGH_COUNT NUMBER NULL, SESSIONS_OPENED_TOTAL_COUNT NUMBER NULL, OBJECT_VERSION_NUMBER NUMBER NULL, CREATION_DATE DATE NULL, CREATED_BY VARCHAR2(200) NULL, LAST_UPDATE_DATE DATE NULL, LAST_UPDATED_BY VARCHAR2(200) NULL, DATA_STATUS VARCHAR2(200) NULL, IND_UPDATE CHAR(1) ) NOLOGGING --No log
8. Insert data into the I $? DMS? Test? Delete? Target table, take the data from the function.c $? Source table, and remove the existing data.
/* DETECTION_STRATEGY = NOT_EXISTS */ insert into FUSION.I$_DMS_TEST_DELET_TARGET ( ID, HOST, PORT, NAME, APPLICATION, CONTEXT_ROOT, SERVICE, PATH, DEPLOYMENT_STATE, SOURCE_INFORMATION, ACTIVE_SERVER_COUNT, SERVLETS, PENDING_REQUESTS, COMPLETED_REQUESTS, OPEN_SESSIONS_CURRENT_COUNT, OPEN_SESSIONS_HIGH_COUNT, SESSIONS_OPENED_TOTAL_COUNT, OBJECT_VERSION_NUMBER, CREATION_DATE, CREATED_BY, LAST_UPDATE_DATE, LAST_UPDATED_BY, DATA_STATUS, IND_UPDATE ) select ID, HOST, PORT, NAME, APPLICATION, CONTEXT_ROOT, SERVICE, PATH, DEPLOYMENT_STATE, SOURCE_INFORMATION, ACTIVE_SERVER_COUNT, SERVLETS, PENDING_REQUESTS, COMPLETED_REQUESTS, OPEN_SESSIONS_CURRENT_COUNT, OPEN_SESSIONS_HIGH_COUNT, SESSIONS_OPENED_TOTAL_COUNT, OBJECT_VERSION_NUMBER, CREATION_DATE, CREATED_BY, LAST_UPDATE_DATE, LAST_UPDATED_BY, DATA_STATUS, IND_UPDATE from ( select SOURCE_A.ID AS ID, SOURCE_A.HOST AS HOST, SOURCE_A.PORT AS PORT, SOURCE_A.NAME AS NAME, SOURCE_A.APPLICATION AS APPLICATION, SOURCE_A.CONTEXT_ROOT AS CONTEXT_ROOT, SOURCE_A.SERVICE AS SERVICE, SOURCE_A.PATH AS PATH, SOURCE_A.DEPLOYMENT_STATE AS DEPLOYMENT_STATE, SOURCE_A.SOURCE_INFORMATION AS SOURCE_INFORMATION, SOURCE_A.ACTIVE_SERVER_COUNT AS ACTIVE_SERVER_COUNT, SOURCE_A.SERVLETS AS SERVLETS, SOURCE_A.PENDING_REQUESTS AS PENDING_REQUESTS, SOURCE_A.COMPLETED_REQUESTS AS COMPLETED_REQUESTS, SOURCE_A.OPEN_SESSIONS_CURRENT_COUNT AS OPEN_SESSIONS_CURRENT_COUNT, SOURCE_A.OPEN_SESSIONS_HIGH_COUNT AS OPEN_SESSIONS_HIGH_COUNT, SOURCE_A.SESSIONS_OPENED_TOTAL_COUNT AS SESSIONS_OPENED_TOTAL_COUNT, SOURCE_A.OBJECT_VERSION_NUMBER AS OBJECT_VERSION_NUMBER, SOURCE_A.CREATION_DATE AS CREATION_DATE, SOURCE_A.CREATED_BY AS CREATED_BY, SOURCE_A.LAST_UPDATE_DATE AS LAST_UPDATE_DATE, SOURCE_A.LAST_UPDATED_BY AS LAST_UPDATED_BY, SOURCE_A.DATA_STATUS AS DATA_STATUS, JRN_FLAG IND_UPDATE from FUSION.C$_0SOURCE SOURCE_A where (1=1) ) S where NOT EXISTS ( select 1 from FUSION.DMS_TEST_DELET_TARGET T where T.ID = S.ID and ((T.HOST = S.HOST) or (T.HOST IS NULL and S.HOST IS NULL)) and ((T.PORT = S.PORT) or (T.PORT IS NULL and S.PORT IS NULL)) and ((T.NAME = S.NAME) or (T.NAME IS NULL and S.NAME IS NULL)) and ((T.APPLICATION = S.APPLICATION) or (T.APPLICATION IS NULL and S.APPLICATION IS NULL)) and ((T.CONTEXT_ROOT = S.CONTEXT_ROOT) or (T.CONTEXT_ROOT IS NULL and S.CONTEXT_ROOT IS NULL)) and ((T.SERVICE = S.SERVICE) or (T.SERVICE IS NULL and S.SERVICE IS NULL)) and ((T.PATH = S.PATH) or (T.PATH IS NULL and S.PATH IS NULL)) and ((T.DEPLOYMENT_STATE = S.DEPLOYMENT_STATE) or (T.DEPLOYMENT_STATE IS NULL and S.DEPLOYMENT_STATE IS NULL)) and ((T.SOURCE_INFORMATION = S.SOURCE_INFORMATION) or (T.SOURCE_INFORMATION IS NULL and S.SOURCE_INFORMATION IS NULL)) and ((T.ACTIVE_SERVER_COUNT = S.ACTIVE_SERVER_COUNT) or (T.ACTIVE_SERVER_COUNT IS NULL and S.ACTIVE_SERVER_COUNT IS NULL)) and ((T.SERVLETS = S.SERVLETS) or (T.SERVLETS IS NULL and S.SERVLETS IS NULL)) and ((T.PENDING_REQUESTS = S.PENDING_REQUESTS) or (T.PENDING_REQUESTS IS NULL and S.PENDING_REQUESTS IS NULL)) and ((T.COMPLETED_REQUESTS = S.COMPLETED_REQUESTS) or (T.COMPLETED_REQUESTS IS NULL and S.COMPLETED_REQUESTS IS NULL)) and ((T.OPEN_SESSIONS_CURRENT_COUNT = S.OPEN_SESSIONS_CURRENT_COUNT) or (T.OPEN_SESSIONS_CURRENT_COUNT IS NULL and S.OPEN_SESSIONS_CURRENT_COUNT IS NULL)) and ((T.OPEN_SESSIONS_HIGH_COUNT = S.OPEN_SESSIONS_HIGH_COUNT) or (T.OPEN_SESSIONS_HIGH_COUNT IS NULL and S.OPEN_SESSIONS_HIGH_COUNT IS NULL)) and ((T.SESSIONS_OPENED_TOTAL_COUNT = S.SESSIONS_OPENED_TOTAL_COUNT) or (T.SESSIONS_OPENED_TOTAL_COUNT IS NULL and S.SESSIONS_OPENED_TOTAL_COUNT IS NULL)) and ((T.OBJECT_VERSION_NUMBER = S.OBJECT_VERSION_NUMBER) or (T.OBJECT_VERSION_NUMBER IS NULL and S.OBJECT_VERSION_NUMBER IS NULL)) and ((T.CREATION_DATE = S.CREATION_DATE) or (T.CREATION_DATE IS NULL and S.CREATION_DATE IS NULL)) and ((T.CREATED_BY = S.CREATED_BY) or (T.CREATED_BY IS NULL and S.CREATED_BY IS NULL)) and ((T.LAST_UPDATE_DATE = S.LAST_UPDATE_DATE) or (T.LAST_UPDATE_DATE IS NULL and S.LAST_UPDATE_DATE IS NULL)) and ((T.LAST_UPDATED_BY = S.LAST_UPDATED_BY) or (T.LAST_UPDATED_BY IS NULL and S.LAST_UPDATED_BY IS NULL)) and ((T.DATA_STATUS = S.DATA_STATUS) or (T.DATA_STATUS IS NULL and S.DATA_STATUS IS NULL)) )
9. Create an index
create index FUSION.I$_DMS_TEST_DELET_TARGET_UK on FUSION.I$_DMS_TEST_DELET_TARGET (ID) NOLOGGING
10.
begin dbms_stats.gather_table_stats( ownname => 'FUSION', tabname => 'I$_DMS_TEST_DELET_TARGET', estimate_percent => dbms_stats.auto_sample_size ); end;
11. Delete the target table identifier D
delete from FUSION.DMS_TEST_DELET_TARGET where exists ( select 'X' from FUSION.I$_DMS_TEST_DELET_TARGET I where FUSION.DMS_TEST_DELET_TARGET.ID = I.ID and IND_UPDATE = 'D' )
12. Delete the temporary insert table with the identifier D
delete from FUSION.I$_DMS_TEST_DELET_TARGET where IND_UPDATE = 'D'
13. Create Checklist
create table FUSION.SNP_CHECK_TAB ( CATALOG_NAME VARCHAR2(100 CHAR) NULL , SCHEMA_NAME VARCHAR2(100 CHAR) NULL , RESOURCE_NAME VARCHAR2(100 CHAR) NULL, FULL_RES_NAME VARCHAR2(100 CHAR) NULL, ERR_TYPE VARCHAR2(1 CHAR) NULL, ERR_MESS VARCHAR2(250 CHAR) NULL , CHECK_DATE DATE NULL, ORIGIN VARCHAR2(250 CHAR) NULL, CONS_NAME VARCHAR2(128 CHAR) NULL, CONS_TYPE VARCHAR2(2 CHAR) NULL, ERR_COUNT NUMBER(10) NULL )
14. Delete data in function.snp "check" tab
delete from FUSION.SNP_CHECK_TAB Middle data where SCHEMA_NAME = 'FUSION' and ORIGIN = '(91)mdsProject.DemoTestUpdateDate' and ERR_TYPE = 'F'
15. Create error tables
create table FUSION.E$_DMS_TEST_DELET_TARGET ( ODI_ROW_ID UROWID, ODI_ERR_TYPE VARCHAR2(1 CHAR) NULL, ODI_ERR_MESS VARCHAR2(250 CHAR) NULL, ODI_CHECK_DATE DATE NULL, ID NUMBER NULL, HOST VARCHAR2(200) NULL, PORT VARCHAR2(200) NULL, NAME VARCHAR2(200) NULL, APPLICATION VARCHAR2(200) NULL, CONTEXT_ROOT VARCHAR2(200) NULL, SERVICE VARCHAR2(200) NULL, PATH VARCHAR2(4000) NULL, DEPLOYMENT_STATE VARCHAR2(200) NULL, SOURCE_INFORMATION VARCHAR2(200) NULL, ACTIVE_SERVER_COUNT NUMBER NULL, SERVLETS NUMBER NULL, PENDING_REQUESTS NUMBER NULL, COMPLETED_REQUESTS NUMBER NULL, OPEN_SESSIONS_CURRENT_COUNT NUMBER NULL, OPEN_SESSIONS_HIGH_COUNT NUMBER NULL, SESSIONS_OPENED_TOTAL_COUNT NUMBER NULL, OBJECT_VERSION_NUMBER NUMBER NULL, CREATION_DATE DATE NULL, CREATED_BY VARCHAR2(200) NULL, LAST_UPDATE_DATE DATE NULL, LAST_UPDATED_BY VARCHAR2(200) NULL, DATA_STATUS VARCHAR2(200) NULL, ODI_ORIGIN VARCHAR2(250 CHAR) NULL, ODI_CONS_NAME VARCHAR2(128 CHAR) NULL, ODI_CONS_TYPE VARCHAR2(2 CHAR) NULL, ODI_PK VARCHAR2(32 CHAR) PRIMARY KEY, ODI_SESS_NO VARCHAR2(36 CHAR) )
16. Delete the last data in the error table
delete from FUSION.E$_DMS_TEST_DELET_TARGET where (ODI_ERR_TYPE = 'S' and 'F' = 'S') or (ODI_ERR_TYPE = 'F' and ODI_ORIGIN = '(91)mdsProject.DemoTestUpdateDate')
17. Create an index
/* FLOW CONTROL CREATE THE INDEX ON I$TABLE */ create index FUSION.I$_DMS_TEST_DELET_TARGET_PK on FUSION.I$_DMS_TEST_DELET_TARGET (ID)
18. Insert data with not only primary key errors into table FUSION.E$_DMS_TEST_DELET_TARGET
insert into FUSION.E$_DMS_TEST_DELET_TARGET ( ODI_PK, ODI_SESS_NO, ODI_ROW_ID, ODI_ERR_TYPE, ODI_ERR_MESS, ODI_ORIGIN, ODI_CHECK_DATE, ODI_CONS_NAME, ODI_CONS_TYPE, ID, HOST, PORT, NAME, APPLICATION, CONTEXT_ROOT, SERVICE, PATH, DEPLOYMENT_STATE, SOURCE_INFORMATION, ACTIVE_SERVER_COUNT, SERVLETS, PENDING_REQUESTS, COMPLETED_REQUESTS, OPEN_SESSIONS_CURRENT_COUNT, OPEN_SESSIONS_HIGH_COUNT, SESSIONS_OPENED_TOTAL_COUNT, OBJECT_VERSION_NUMBER, CREATION_DATE, CREATED_BY, LAST_UPDATE_DATE, LAST_UPDATED_BY, DATA_STATUS ) select SYS_GUID(), '28d4ac47-7a0a-408b-b050-9631a3fe5510', rowid, 'F', 'ODI-15064: Primary key DMS_TEST_DELET_TARGET_PK Not the only one.', '(91)mdsProject.DemoTestUpdateDate', sysdate, 'DMS_TEST_DELET_TARGET_PK', 'PK', TARGET.ID, TARGET.HOST, TARGET.PORT, TARGET.NAME, TARGET.APPLICATION, TARGET.CONTEXT_ROOT, TARGET.SERVICE, TARGET.PATH, TARGET.DEPLOYMENT_STATE, TARGET.SOURCE_INFORMATION, TARGET.ACTIVE_SERVER_COUNT, TARGET.SERVLETS, TARGET.PENDING_REQUESTS, TARGET.COMPLETED_REQUESTS, TARGET.OPEN_SESSIONS_CURRENT_COUNT, TARGET.OPEN_SESSIONS_HIGH_COUNT, TARGET.SESSIONS_OPENED_TOTAL_COUNT, TARGET.OBJECT_VERSION_NUMBER, TARGET.CREATION_DATE, TARGET.CREATED_BY, TARGET.LAST_UPDATE_DATE, TARGET.LAST_UPDATED_BY, TARGET.DATA_STATUS from FUSION.I$_DMS_TEST_DELET_TARGET TARGET where exists ( select SUB.ID from FUSION.I$_DMS_TEST_DELET_TARGET SUB where SUB.ID=TARGET.ID group by SUB.ID having count(1) > 1 )--Check primary key duplication
19. Insert null error data into table FUSION.E$_DMS_TEST_DELET_TARGET
insert into FUSION.E$_DMS_TEST_DELET_TARGET ( ODI_PK, ODI_SESS_NO, ODI_ROW_ID, ODI_ERR_TYPE, ODI_ERR_MESS, ODI_CHECK_DATE, ODI_ORIGIN, ODI_CONS_NAME, ODI_CONS_TYPE, ID, HOST, PORT, NAME, APPLICATION, CONTEXT_ROOT, SERVICE, PATH, DEPLOYMENT_STATE, SOURCE_INFORMATION, ACTIVE_SERVER_COUNT, SERVLETS, PENDING_REQUESTS, COMPLETED_REQUESTS, OPEN_SESSIONS_CURRENT_COUNT, OPEN_SESSIONS_HIGH_COUNT, SESSIONS_OPENED_TOTAL_COUNT, OBJECT_VERSION_NUMBER, CREATION_DATE, CREATED_BY, LAST_UPDATE_DATE, LAST_UPDATED_BY, DATA_STATUS ) select SYS_GUID(), '28d4ac47-7a0a-408b-b050-9631a3fe5510', rowid, 'F', 'ODI-15066: column ID Can't be null.', sysdate, '(91)mdsProject.DemoTestUpdateDate', 'ID', 'NN', ID, HOST, PORT, NAME, APPLICATION, CONTEXT_ROOT, SERVICE, PATH, DEPLOYMENT_STATE, SOURCE_INFORMATION, ACTIVE_SERVER_COUNT, SERVLETS, PENDING_REQUESTS, COMPLETED_REQUESTS, OPEN_SESSIONS_CURRENT_COUNT, OPEN_SESSIONS_HIGH_COUNT, SESSIONS_OPENED_TOTAL_COUNT, OBJECT_VERSION_NUMBER, CREATION_DATE, CREATED_BY, LAST_UPDATE_DATE, LAST_UPDATED_BY, DATA_STATUS from FUSION.I$_DMS_TEST_DELET_TARGET where ID is null
20. Create an index for FUSION.E$_DMS_TEST_DELET_TARGET
/* FLOW CONTROL CREATE INDEX ON THE E$TABLE */ create index FUSION.E$_DMS_TEST_DELET_TARGET_IDX on FUSION.E$_DMS_TEST_DELET_TARGET (ODI_ROW_ID)
21. Delete the wrong rows from the insert table (rows in the error table)
delete from FUSION.I$_DMS_TEST_DELET_TARGET T where exists ( select 1 from FUSION.E$_DMS_TEST_DELET_TARGET E where ODI_SESS_NO = '28d4ac47-7a0a-408b-b050-9631a3fe5510' and T.rowid = E.ODI_ROW_ID )
22. Insert data into FUSION.SNP_CHECK_TAB
insert into FUSION.SNP_CHECK_TAB Insert data in ( SCHEMA_NAME, RESOURCE_NAME, FULL_RES_NAME, ERR_TYPE, ERR_MESS, CHECK_DATE, ORIGIN, CONS_NAME, CONS_TYPE, ERR_COUNT ) select 'FUSION', 'DMS_TEST_DELET_TARGET', 'FUSION.DMS_TEST_DELET_TARGET', E.ODI_ERR_TYPE, E.ODI_ERR_MESS, E.ODI_CHECK_DATE, E.ODI_ORIGIN, E.ODI_CONS_NAME, E.ODI_CONS_TYPE, count(1) from FUSION.E$_DMS_TEST_DELET_TARGET E where E.ODI_ERR_TYPE = 'F' and E.ODI_ORIGIN = '(91)mdsProject.DemoTestUpdateDate' group by E.ODI_ERR_TYPE, E.ODI_ERR_MESS, E.ODI_CHECK_DATE, E.ODI_ORIGIN, E.ODI_CONS_NAME, E.ODI_CONS_TYPE
23. Update the ID in FUSION.I$_DMS_TEST_DELET_TARGET that already exists in FUSION.DMS_TEST_DELET_TARGET as the data identifier U (Update), and then update it.
/* DETECTION_STRATEGY = NOT_EXISTS */ update FUSION.I$_DMS_TEST_DELET_TARGET set IND_UPDATE = 'U' where (ID) in ( select ID from FUSION.DMS_TEST_DELET_TARGET )
24. Identify invalid rows
/* DETECTION_STRATEGY = NOT_EXISTS */ /* Command skiped due to chosen DETECTION_STRATEGY */
25.Disable constraints
26.Disable indexes
27. Update existing rows
/* DETECTION_STRATEGY = NOT_EXISTS */ update FUSION.DMS_TEST_DELET_TARGET T set ( T.HOST, T.PORT, T.NAME, T.APPLICATION, T.CONTEXT_ROOT, T.SERVICE, T.PATH, T.DEPLOYMENT_STATE, T.SOURCE_INFORMATION, T.ACTIVE_SERVER_COUNT, T.SERVLETS, T.PENDING_REQUESTS, T.COMPLETED_REQUESTS, T.OPEN_SESSIONS_CURRENT_COUNT, T.OPEN_SESSIONS_HIGH_COUNT, T.SESSIONS_OPENED_TOTAL_COUNT, T.OBJECT_VERSION_NUMBER, T.CREATION_DATE, T.CREATED_BY, T.LAST_UPDATE_DATE, T.LAST_UPDATED_BY, T.DATA_STATUS ) = ( select S.HOST, S.PORT, S.NAME, S.APPLICATION, S.CONTEXT_ROOT, S.SERVICE, S.PATH, S.DEPLOYMENT_STATE, S.SOURCE_INFORMATION, S.ACTIVE_SERVER_COUNT, S.SERVLETS, S.PENDING_REQUESTS, S.COMPLETED_REQUESTS, S.OPEN_SESSIONS_CURRENT_COUNT, S.OPEN_SESSIONS_HIGH_COUNT, S.SESSIONS_OPENED_TOTAL_COUNT, S.OBJECT_VERSION_NUMBER, S.CREATION_DATE, S.CREATED_BY, S.LAST_UPDATE_DATE, S.LAST_UPDATED_BY, S.DATA_STATUS from FUSION.I$_DMS_TEST_DELET_TARGET S where T.ID =S.ID ) where (ID) in ( select ID from FUSION.I$_DMS_TEST_DELET_TARGET where IND_UPDATE = 'U' )
28. Insert non-existent rows
/* DETECTION_STRATEGY = NOT_EXISTS */ insert into FUSION.DMS_TEST_DELET_TARGET T ( ID, HOST, PORT, NAME, APPLICATION, CONTEXT_ROOT, SERVICE, PATH, DEPLOYMENT_STATE, SOURCE_INFORMATION, ACTIVE_SERVER_COUNT, SERVLETS, PENDING_REQUESTS, COMPLETED_REQUESTS, OPEN_SESSIONS_CURRENT_COUNT, OPEN_SESSIONS_HIGH_COUNT, SESSIONS_OPENED_TOTAL_COUNT, OBJECT_VERSION_NUMBER, CREATION_DATE, CREATED_BY, LAST_UPDATE_DATE, LAST_UPDATED_BY, DATA_STATUS ) select ID, HOST, PORT, NAME, APPLICATION, CONTEXT_ROOT, SERVICE, PATH, DEPLOYMENT_STATE, SOURCE_INFORMATION, ACTIVE_SERVER_COUNT, SERVLETS, PENDING_REQUESTS, COMPLETED_REQUESTS, OPEN_SESSIONS_CURRENT_COUNT, OPEN_SESSIONS_HIGH_COUNT, SESSIONS_OPENED_TOTAL_COUNT, OBJECT_VERSION_NUMBER, CREATION_DATE, CREATED_BY, LAST_UPDATE_DATE, LAST_UPDATED_BY, DATA_STATUS from FUSION.I$_DMS_TEST_DELET_TARGET S where IND_UPDATE = 'I'
29.Enable Index
30.Enable constraints
31. Submission
/*commit*/
32. Delete worksheets
drop table FUSION.C$_0SOURCE purge
33. Delete insert table
drop table FUSION.I$_DMS_TEST_DELET_TARGET Delete Insert Table
Unlock subscribers
1. Verification Version
DECLARE -- Validating KM options dbVersion1 NUMBER(2,0); dbVersion2 NUMBER(2,0); BEGIN -- Verify RDBMS version select case when upper(name) = 'COMPATIBLE' then to_number(substr(value, 1, instr(value, '.',1,1)-1)) else null end v0, case when upper(name) = 'COMPATIBLE' then to_number(substr(value, instr(value, '.',1,1)+1, instr(value, '.',1,2)-instr(value, '.',1,1)-1)) else null end v1 into dbVersion1, dbVersion2 from v$parameter where upper(name) = 'COMPATIBLE'; IF dbVersion1 < 9 THEN raise_application_error(-20101, 'ODIKM-ORA-10000: You are using RDBMS version '||dbVersion1||'.'||dbVersion2||'. This version does not support JKM COMPATIBLE= 9.'); END IF; END;
2. Setting parameters
import java.sql as sql import java.lang as lang # Connect to the Source Database ie the one that hosts the journalized tables myCon = odiRef.getJDBCConnection("SRC") # Create the list of Subscribers for a CDC Set lstSbs = [] lstSbs.append('Zero')
3.
updCmd = """ update FUSION.SNP_CDC_SUBS SUBS set SUBS.MIN_WINDOW_ID = SUBS.MAX_WINDOW_ID_INS where SUBS.CDC_SET_NAME = 'FUSION.FUSIONTABLEUPDATEDEMO' and SUBS.CDC_SUBSCRIBER = ? """ # Prepare the update prepUpdStmt = myCon.prepareStatement(updCmd) # Execute it for each subscriber for sbs in lstSbs: prepUpdStmt.setString(1, sbs) nbRows = prepUpdStmt.executeUpdate() prepUpdStmt.close() # Commit the updates myCon.commit()
4. Close the connection
myCon.close()
Clear diary
1. Verification Version
DECLARE -- Validating KM options dbVersion1 NUMBER(2,0); dbVersion2 NUMBER(2,0); BEGIN -- Verify RDBMS version select case when upper(name) = 'COMPATIBLE' then to_number(substr(value, 1, instr(value, '.',1,1)-1)) else null end v0, case when upper(name) = 'COMPATIBLE' then to_number(substr(value, instr(value, '.',1,1)+1, instr(value, '.',1,2)-instr(value, '.',1,1)-1)) else null end v1 into dbVersion1, dbVersion2 from v$parameter where upper(name) = 'COMPATIBLE'; IF dbVersion1 < 9 THEN raise_application_error(-20101, 'ODIKM-ORA-10000: You are using RDBMS version '||dbVersion1||'.'||dbVersion2||'. This version does not support JKM COMPATIBLE= 9.'); END IF; END;
2. Delete synchronized data
/* Delete rows from journalizing tables that are useless for each subscriber */ delete from FUSION.J$DMS_TEST_DELET_SOURCE JRN where JRN.WINDOW_ID <= ( select min(SUBS.MIN_WINDOW_ID) from FUSION.SNP_CDC_SUBS SUBS where SUBS.CDC_SET_NAME = 'FUSION.FUSIONTABLEUPDATEDEMO' )
3. Close the connection once and end the CDC synchronization
myCon.close()