September 26, 2006 at 1:09 pm
I am using DTS packages to import data from an oracle v10 database to an SQL 2000 database.
In the DTS package I use an SQL query that looks like this :
SELECT * from <tablename> or instead of * I use fieldnames
My problem is that I can't get the date fields imported in SQL. Which statement should I use for this ??
September 27, 2006 at 2:56 am
Hi
Have you tried importing the date fields into a varchar?
Regards
Mike
September 27, 2006 at 6:04 am
Ofcourse I tried that and ofcourse it works ... but that's not what I want as a result. The field must be a datetime field !
After the import I link the tables in Microsoft Access and that's why the fields must be datetime because in Access datetime statements are used ...
September 27, 2006 at 6:28 am
why can't you import into SQL , and after the import is completed alter the column definition to be a datetime field, or add datetime columns and migrate the data to the new columns?
then the new columns could be the columns you send to MS Access, instead of the varchar originals.
I usually migrate data from oracle to staging tables exactly because of this issue, and then move the data from staging tables to their final destination.
Lowell
September 27, 2006 at 6:36 am
Hi
I do not have a Oracle server to test this on...But I am guessing you are using a Transform Data Task to get the data into your DB....Can you not go to the transformation and delete the one that is the date...Then re-add it set it as an ActiveX transformation then format the date so that it is in the correct format?
Mike
September 27, 2006 at 9:10 am
That is exactly what I did and that didn't work ! But ... I'm a little new to SQL and ActiveX is also new for me so maybe I'm not using the right VB commands. I let VB autogen the command for me but that doesn't work ??
September 27, 2006 at 8:47 pm
Use an sql statement with the openquery function, something like:
insert mySQLServer table select ..., convert(datetime, myvarchardate)
from openquery(myOracleServer, 'select ..., munge(cast myOracledate as varchar) as myvarchardate from myOracleTable')
...where munge() is the oracle substr(), etc., to get the date into a character representation that sql server recognizes, i.e. 'yyyy-mm-dd hh:mm:ss'
September 27, 2006 at 11:16 pm
I suspect that the problem might be that in Oracle the minimum allowed date is 1753-01-01, whereas in SQL Server it is 1900-01-01. When the DTS tries to load that record, SQL Server sees it as an invalid date and throws an error. When you specify the destination field as Varchar, SQL Server just views it as text and doesn't check to see if is a valid date as far as SQL server is concerned.
You may be able to add an ActiveX script in your Data Pump Task to check for that and convert the year to 1900. Better still, load the data into a staging table first where the date field type is Varchar, and then use a stored proc to check and adjust the date to make it SQL Server valid, and then finally load it into your production table which has the field as a type Datetime.
September 28, 2006 at 7:06 am
I'm now using an ActiveX script like this :
If IsDate(DTSSource("T$LVDT")) Then
If DateValue(DTSSource("T$LVDT")) < DateValue("01-01-1753") Then
DTSDestination("Verificatiedatum") = DateValue("01-01-1753")
Else
DTSDestination("Verificatiedatum") = DTSSource("T$LVDT")
End If
Else
DTSDestination("Verificatiedatum") = NULL
End If
and it works !!! But ... it is much slower ?? Any suggestions to speed this one up ??
September 28, 2006 at 8:41 am
In oracle, if you want to convert the date to character format, you don't use convert. In the SQL task, you have to convert the date to character format,
the syntax is
TO_CHAR(sysdate, 'MM/DD/YYYY') it would return '09/29/2006'
September 28, 2006 at 8:50 am
That's correct, I'm using
TO_CHAR("T$DDAT", 'mm-dd-yyyy') AS "T$DDAT"
in my SQL query, and
If IsDate(DTSSource("T$DDAT")) Then
If DateValue(DTSSource("T$DDAT")) < DateValue("01-01-1753") Then
DTSDestination("Leverdatum") = DateValue("01-01-1753")
Else
DTSDestination("Leverdatum") = DTSSource("T$DDAT")
End If
Else
DTSDestination("Leverdatum") = NULL
End If
in my ActiveX script.
The above is working, but not as quick as I would like it to be !
September 28, 2006 at 10:07 am
It would be faster to use the Staging table approach. While the ActiveX script approach works, it slows your transfer speed down. By using a staging table where the field type is varchar, a stored proc to fix the dates, and finally to move the data into a production table where the field type is datetime, the DTS will complete much faster.
September 28, 2006 at 12:40 pm
Can you explain in detail what you mean with staging table ?
September 28, 2006 at 5:51 pm
Sure. Create a table in SQL Server with all the fields that you are pulling from Oracle. We'll name the table "Staging" for now. In that table, make the fields that are date related as varchar fields.
Next, create a table in SQL Server with all the same fields that you created in Staging. We'll name this table "Production" for now. In that table, make the fields that are date related as datetime fields.
In your DTS package, the first thing is to create a Execute SQL Task with the command:
truncate table Staging
Next step, have your Data Pump Task load the Oracle data into the "Staging" table. Once that has completed, The third step is to use a Execute SQL Query task (pointing to your destination database, of course) with an update statement that says:
update Staging
set DateField = '1900-01-01'
where DateField = '1753-01-01'
go
You could do additional data scrubbing at this point too.
That will correct the dates so that SQL will accept them and is much faster than ActiveX. Finally the last step, (and I'm assuming you are refreshing the entire table each time) delete the existing data from the Production table and move the data from the Staging table into it, like so:
truncate table production
go
insert Production (Field1, Field2,...)
select Field1, Field2,... from Staging
go
You could use CAST or CONVERT on the date fields if you like, but so long as the dates are valid, SQL will implicitly convert them to datetime, as the destination field is of datetime type. Anyway, SQL should accept the dates as valid datetime values.
The bonus is that if you had deleted the data from the Production table first, tried to copy the data from Oracle into it, and that task failed for some reason (Oracle server offline, network probs, etc), you would end up with an empty Production table. Generally not good. With the Staging table approach, if the data transfer failed for some reason, your existing Production data would be un-affected. It is very unlikely that a DELETE and INSERT would fail if both Staging and Production tables are in the same DB.
Hope this helps.
September 28, 2006 at 7:26 pm
I don't know about Oracle date ranges, but the difference between '1753-01-01' and '1900-01-01' is between the minimum value for a SQL Server datetime datatype (8 bytes with resolution to 300 ms) vs. the minimum value for a SQL Server smalldatetime datatype (4 bytes with resolution to 1 minute). I would bet that this is not the source of your problem. More likely is that Oracle's character representation is different from SQL Server's (at least if time is included) so must be converted even if translated to varchar.
Viewing 15 posts - 1 through 15 (of 16 total)
You must be logged in to reply to this topic. Login to reply