Friday, 11 February 2011

FLOAT data type migration

Sybase FLOAT is generally used to save non integer numbers like fractions where no number of precision can hold the exact value. Sybase FLOATs do not store an exact value
"It stores slightly imprecise representations of real numbers as binary fractions at the hardware level"
http://www.sybase.com/detail?id=20313

Oracle has two data types, FLOAT and BINARY_FLOAT.
http://stackoverflow.com/questions/332492/oracle-floats-vs-number
  • FLOAT is really a decimal data type with exact values (basically it is a NUMERIC)
  • BINARY_FLOAT is a binary data type which better maps to Sybase FLOAT data type
If you migrate from Sybase FLOAT to Oracle FLOAT any value inserted will be treated as a specific explicit numeric, which will not behave like Sybase FLOAT.
If you migrate from Sybase FLOAT to Oracle BINARY_FLOAT then any value inserted will be treated as a binary imprecise number, just like Sybase.

SYBASE
drop table testfloat
go
create table testfloat (floatcol float)
go
insert into testfloat values(1.005)
go
insert into testfloat values(1.0049999999999999)
go
select * from testfloat --both values are displayed as 1.005
go
select * from testfloat where floatcol = 1.005 --returns both rows
go
select * from testfloat where floatcol = 1.0049999999999999 --returns both rows
go
select * from testfloat where floatcol = 1.0049999999999998 --returns both rows
go
select * from testfloat where floatcol = 1.0049999999999997 --returns NO rows
go
select * from testfloat where floatcol = 1.004999994--returns NO rows
go
select * from testfloat where floatcol = 1.004999493 --returns NO rows
go

So it looks like Sybase stores 1.005 as 1.0049999999999999, but displays it to the clients (like isql, jdbc) as 1.005
A comparison can be made with the literal 1.005 (though not recommended as float should never be compared in this way)

ORACLE
DROP table testfloat;
create table testfloat(floatcol float, binaryfloatcol binary_float ,varchar2floatcol varchar2(100) );
insert into testfloat values(1.005,1.005,'1.005') ;
insert into testfloat values(1.0049999999999999,1.0049999999999999,'1.0049999999999999');
select * from testfloat; --both values are displayed as 1.005 for BINARY_FLOAT and a mix as FLOAT
select * from testfloat where floatcol = 1.005; --returns one row
select * from testfloat where floatcol = 1.0049999999999999 ; --returns one row
select * from testfloat where floatcol = 1.0049999999999998 ; --returns NO rows
select * from testfloat where floatcol = 1.0049999999999997 ; --returns NO rows

select * from testfloat where binaryfloatcol = 1.005; --returns two rows
select * from testfloat where binaryfloatcol = 1.0049999999999999 ; --returns two rows
select * from testfloat where binaryfloatcol = 1.0049999999999998 ; --returns two rows
select * from testfloat where binaryfloatcol = 1.0049999999999997 ; --returns two rows

select * from testfloat where binaryfloatcol = 1.004999994 ; --returns two rows
select * from testfloat where binaryfloatcol = 1.004999493 ; --returns no row

Oracle stores FLOAT values as explicit numbers whereas BINARY_FLOAT values are not as precise. Oracle also displays 1.005 for both values in BINARY_FLOAT.

Conclusion
From the above test cases it looks like Oracle BINARY_FLOAT is a much better match than Oracle FLOAT for Sybase FLOAT, but it should be noted that since Sybase FLOAT and Oracle BINARY_FLOAT are not precise numbers , comparing equivalence is not identical between databases.

floats , be they Sybase FLOATs or Oracle BINARY_FLOATs should never be directly compared, rather a range of values should be matched.

Notes
Sybase BCP dumps out both floats as 1.0049999999999999
JDBC query against Sybase returns both floats as 1.005.

So during a SQL Developer data move, online will insert 1.005 , but offline will insert 1.0049999999999999. This doesn't really matter if the Oracle data type is BINARY_FLOAT, but it does if you use Oracle FLOAT data type.

Wednesday, 9 February 2011

Migration Reports 3.0

We have revamped the migration reports in SQL Developer 3.0 to provide significantly more information about your migration. Instead of "hiding" this information under the Migration Report navigator , now the reports can be viewed by double clicking on any of the folder nodes in the Migration navigator. The reports are smart enough to tailor the information depending on where in the Migration Navigator you click.


Status

Gives you a heads up of the status of each migration project/model.
Also provides links which when double clicked, launch the migration wizard to perform the appropriate action


Summary

Provides the number of objects (tables, procedures, views , ... ) involved in each of the migration projects.It then breaks down into the number of objects in each database or owner.


Analysis

Provides fine grain details about the databases and objects being migrated.
SQL Size Chart
Visualize size of all SQL Objects
SQL Size Summary
Number of SQL Objects with similar sizes
SQL Size Details
Line size for every SQL Object
Columns
Details of all captured colums
Name Changes
All the name changes between the captured objects and the converted objects
Dependencies
Dependency tree between store procedures and other objects

Temporary Table Summary
Summary of the number of temporary tables per project / database
Temporary Table Details
List of all temporary tables identified and their parent procedure
Parameters
List of all procedure and function parameters including new params


Capture Issues

There should be no capture issues, but if an issues occurs it will be listed here


Conversion Status

Lists the number of Procedures, Triggers and Views which converted or failed to convert

Conversion Issues

Reports on all the issues which where encountered during the conversion.
Errors denote objects which failed to convert.
Limitations denote objects which converted but a particular statement or clause was not supported


Target Status

After selecting an appropriate connection to the target database and clicking refresh, this report will list all the objects in the converted model and their status in the target database. Valid, Invalid or Missing


Target Issues

After choosing the appropriate Target connection and clicking refresh, this looks at the issues of each object in the target database.


Data Quality

After selecting the appropriate
Model, Source Connection and Target Connection click Analysis.

You will be prompted to continue as you are reminded that a full table scan of all the tables on the source connection and target connection will take place.


SELECT count(*) from tablename is performed against each table and the values inserted into the migration repository.

Once complete, click refresh. Each table migrated is listed with the source row number and the target row number, making it easy to identify tables where all the data was not migrated

Note that SELECT count(*) from tablename may make a significant impact on the performance of the source and target database so best run only on non production databases.


Model Comparison

After choosing the first captured model and the second captured model click refresh. The differences between the models will be listed.

This is useful when trying to identify changes to your source database over a period of time , sometimes called the delta.

This knowledge can help identify any new or modified objects which require migration.