Dealing with invalid dates
In some cases the source application may insert an invalid date into an Oracle DATE field.Â
For example a value of ’0000-00-00 00:00:00′  has been inserted into an Oracle DATE field. This is an invalid date as far as Oracle is concerned. This will be replicated into the target database as a NULL, but in some cases this may not be desirable. It maybe desirable to replace the NULL with a specific date.
This is possible by using the  _MINE_FIX_INVALID_DATE_NEW_VALUE setting.
Example:
set _MINE_FIX_INVALID_DATE_NEW_VALUE = 77640101010101
This is the hex equivalent of 1900-01-01 00:00:00. If the source date is invalid, then the target date will be: 1900.01.01 00:00:00. For an update statement where the invalid date is part of the WHERE clause, the new value of date will also be used.
Â
In the following example END_DATE contained an invalid date value and has been changed to a valid date:
DELETE from AVI."INVALID_DATE" where (1=1) and PID = 101 and ORDER_NUMBER = 200 and START_DATE = 2012.09.15 15:24:26 and END_DATE = 1900.01.01 00:00:00
Â
Invalid date with valid time component
In the case where the time component is valid, but the date component is not valid, the following can be set:
set _MINE_FIX_INVALID_DATE_NEW_VALUE = 77640101FFFFFF
This will keep the time component of the whole date but will only replace the date component with 1900.01.01.
Â
Here is an example. We are replicating the whole schema called AVI.
Ensure we have the _MINE_FIX_INVALID_DATE_NEW_VALUE set:
dbvrep> set _MINE_FIX_INVALID_DATE_NEW_VALUE = 77640101FFFFFF
The MINE process will have to be restarted after setting this to take affect.
Â
Lets create a new table on the source database:
create table invalid_date ( pid number, order_number number, start_date date, end_date date );
Â
Now lets insert an invalid date with a correct time component into this table:
export SOURCE_TNS=d112f sqlplus -s avi/xxx@${SOURCE_TNS}<<SQL truncate table invalid_date; declare d date; begin dbms_stats.convert_raw_value('64640001182e0e', d); insert into invalid_date values (601, 200, sysdate, d); insert into invalid_date values (701, 200, sysdate, d); end; / SQL
Â
We will also update the row with PID=601:
sqlplus -s avi/xxx@${SOURCE_TNS}<<SQL declare d date; begin dbms_stats.convert_raw_value('64640001162f0f', d); update invalid_date set end_date = d where pid = 601; end; / SQL
Â
Now lets select from this table to see what we have at the source database:
sqlplus -s avi/xxx@${SOURCE_TNS}<<SQL alter session set nls_date_format='YYYY.DD.MM HH24:MI:SS'; select PID, END_DATE from avi.invalid_date; SQL
Â
The result from the source table is as follows:
PID END_DATE ---- ------------------- 601 0000.01.00 21:46:14 701 0000.01.00 23:45:13
Â
We can see that the date component is invalid, but the time component is correct.
TARGET
Dbvisit Replicate will replicate the changes and substitute them based on _MINE_FIX_INVALID_DATE_NEW_VALUE.
Â
TO_CHAR(END_DATE,'Y ------------------- 1900-01-01 21:46:14 1900-01-01 23:45:13 DUMP(END_DATE,16) -------------------------------------------------------------------------------- Typ=12 Len=7: 77,64,1,1,16,2f,f Typ=12 Len=7: 77,64,1,1,18,2e,e
Â
We see that the time component has been kept, but the date component has been set to 1900-01-01.
Â