By Welly Lee, Pinaki Bag, and Jayakumar Tanneru.
Oracle has an object data type called anydata. This data type supports wide range of data types. For example when creating a table with a column defined as anydata type, the column can store many types of data from string to numeric . SSMA does not support migration of anydata and when migrating Oracle database containing the type, SSMA raise a migration error O2SS0005: Source datatype not recognized.
SQL Server has a similar data type called sql_variant. sql_variant provides simpler data management and provide additional capabilities:
Oracle
SQL Server
CREATE TABLE tbl1 (col1 anydata);
CREATE TABLE tbl1 (col1 sql_variant)
INSERT INTO tbl1 (col1) VALUES (sys.anydata.convertnumber(123.4));
INSERT INTO tbl1 (col1) VALUES (123.4)
INSERT INTO tbl1 (col1) VALUES (sys.anydata.convertvarchar2('abc'));
INSERT INTO tbl1 (col1) VALUES ('abc')
INSERT INTO tbl1 (col1) VALUES (sys.anydata.convertdate(sysdate));
INSERT INTO tbl1 (col1) VALUES (getdate())
/* note that a sql_variant data type must first be cast to its base data type value before participating in operations such as addition and subtraction. For example: */
For many cases, sql_variant can be used to replace anydata type when migrating Oracle to SQL Server. However, note the following limitation:
If you are unable to use sql_variant due to the technical limitation above, you may consider to migrate the anydata as separate columns based on its individual types (SQL Server 2008 supports Sparse Column to optimize storing data across multiple columns with many NULL values). Alternatively, you can also consider to convert anydata to xml type (note the limitations of xml data type)
-- Sample SQL Server Statements: CREATE TABLE tbl1 (col1 xml) INSERT INTO tbl1 VALUES ('<root><data>123.4</data><datatype>decimal(13,5)</datatype></root>') INSERT INTO tbl1 VALUES ('<root><data>abc</data><datatype>varchar(max)</datatype></root>') INSERT INTO tbl1 VALUES ('<root><data>'+cast(getdate() as varchar(max))+'</data><datatype>datetime</datatype></root>') SELECT col1.value('(/root/data)[1]','varchar(max)') from tbl1 -- returning data values SELECT col1.value('(/root/datatype)[1]','varchar(max)') from tbl1 -- returning data types
REFERENCE
SQL Server 2008R2 Books Online : sql_variant