OracleDataAdapter Safe Type Mapping
The ODP.NET OracleDataAdapter
class provides the Safe Type Mapping feature to ensure that the following Oracle data types do not lose data when converted to their closely related .NET types in the DataSet
:
-
NUMBER
-
DATE
-
TimeStamp
(refers to allTimeStamp
objects) -
INTERVAL
DAY
TO
SECOND
Note:
ODP.NET, Managed Driver and ODP.NET do not support Safe Type Mapping.
This section includes the following topics:
Comparison Between Oracle Data Types and .NET Types
The following sections provide more details about the differences between the Oracle data types and the corresponding .NET types. In general, the Oracle data types allow a greater degree of precision than the .NET types do.
Oracle NUMBER Type to .NET Decimal Type
The Oracle data type NUMBER
can hold up to 38 precision, and the .NET Decimal
type can hold up to 28 precision. If a NUMBER
data type that has more than 28 precision is retrieved into a .NET Decimal
type, it loses precision.
Table 3-28 lists the maximum and minimum values for Oracle NUMBER
and .NET Decimal
types.
Table 3-28 Oracle NUMBER to .NET Decimal Comparisons
Value Limits | Oracle NUMBER | .NET Decimal |
---|---|---|
Maximum |
9.9999999999999999999999999999999999999 e125 |
79,228,162,514,264,337,593,543,950,335 |
Minimum |
-9.9999999999999999999999999999999999999 e125 |
-79,228,162,514,264,337,593,543,950,335 |
Oracle Date Type to .NET DateTime Type
The Oracle data type DATE
can represent dates in BC whereas the .NET DateTime
type cannot. If a DATE
that goes to BC get retrieved into a .NET DateTime
type, it loses data.
Table 3-29 lists the maximum and minimum values for Oracle Date
and .NET DateTime
types.
Table 3-29 Oracle Date to .NET DateTime Comparisons
Value Limits | Oracle Date | .NET DateTime |
---|---|---|
Maximum |
Dec 31, 9999 AD |
Dec 31, 9999 AD 23:59:59.9999999 |
Minimum |
Jan 1, 4712 BC |
Jan 1, 0001 AD 00:00:00.0000000 |
Oracle TimeStamp Type to .NET DateTime Type
Similar to the DATE
data type, the Oracle TimeStamp
data type can represent a date in BC, and a .NET DateTime
type cannot. If a TimeStamp
that goes to BC is retrieved into a.NET DateTime
type, it loses data. The Oracle TimeStamp
type can represent values in units of e-9; the .NET DateTime
type can represent only values in units of e-7. The Oracle TimeStamp
with time zone data type can store time zone information, and the .NET DateTime
type cannot.
Table 3-30 lists the maximum and minimum values for Oracle TimeStamp
and .NET DateTime
types.
Table 3-30 Oracle TimeStamp to .NET DateTime Comparisons
Value Limits | Oracle TimeStamp | .NET DateTime |
---|---|---|
Maximum |
Dec 31, 9999 AD 23:59:59.999999999 |
Dec 31, 9999 AD 23:59:59.9999999 |
Minimum |
Jan 1, 4712 BC 00:00:00.000000000 |
Jan 1, 0001 AD 00:00:00.0000000 |
Oracle INTERVAL DAY TO SECOND to .NET TimeSpan
The Oracle data type INTERVAL
DAY
TO
SECOND
can hold up to 9 precision, and the .NET TimeSpan type can hold up to 7 precision. If an INTERVAL
DAY
TO
SECOND
data type that has more than 7 precision is retrieved into a .NET TimeSpan type, it loses precision. The Oracle INTERVAL
DAY
TO
SECOND
type can represent values in units of e-9, and the .NET TimeSpan
type can represent only values in units of e-7.
Table 3-31 lists the maximum and minimum values for Oracle INTERVAL
DAY
TO
SECOND
and .NET DateTime
types.
Table 3-31 Oracle INTERVAL DAY TO SECOND to .NET TimeSpan Comparisons
Value Limits | Oracle INTERVAL DAY TO SECOND | .NET TmeSpan |
---|---|---|
Maximum |
+999999999 23:59:59.999999999 |
+10675199 02:48:05.4775807 |
Minimum |
-999999999 23:59:59.999999999 |
-10675199 02:48:05.4775808 |
SafeMapping Property
The OracleDataAdapter
Safe Type Mapping feature prevents data loss when populating Oracle data for any of these types into a .NET DataSet
. By setting the SafeMapping
property appropriately, these types can be safely represented in the DataSet
, as either of the following:
-
.NET
byte[]
in Oracle format -
.NET
String
By default, Safe Type Mapping is disabled.
Using Safe Type Mapping
To use the Safe Type Mapping feature, the OracleDataAdapter
.SafeMapping
property must be set with a hash table of key-value pairs. The key-value pairs must map database table column names (of type string
) to a .NET type (of type Type
). ODP.NET supports Safe Type Mapping to byte[]
and String
types. Any other type mapping causes an exception.
In situations where the column names are not known at design time, an asterisk ("*") can be used to map all occurrences of database types to a safe .NET type. If both the valid column name and the asterisk are present, the column name is used.
Note:
-
Database table column names are case-sensitive.
-
Column names in the hash table that correspond to invalid column names are ignored.
Safe Type Mapping as a string is more readable without further conversion. Converting certain Oracle data types to a string requires extra conversion, which can be slower than converting it to a byte[]
. Conversion of .NET strings back to ODP.NET types relies on the formatting information of the session.
SafeTyping Example
// C# using System; using System.Data; using Oracle.DataAccess.Client; class SafeMappingSample { static void Main() { string constr = "User Id=scott;Password=tiger;Data Source=oracle"; // In this SELECT statement, EMPNO, HIREDATE and SALARY must be // preserved using safe type mapping. string cmdstr = "SELECT EMPNO, ENAME, HIREDATE, SAL FROM EMP"; // Create the adapter with the selectCommand txt and the connection string OracleDataAdapter adapter = new OracleDataAdapter(cmdstr, constr); // Get the connection from the adapter OracleConnection connection = adapter.SelectCommand.Connection; // Create the safe type mapping for the adapter // which can safely map column data to byte arrays, where // applicable. By executing the following statement, EMPNO, HIREDATE AND // SALARY columns will be mapped to byte[] adapter.SafeMapping.Add("*", typeof(byte[])); // Map HIREDATE to a string // If the column name in the EMP table is case-sensitive, // the safe type mapping column name must be case-sensitive. adapter.SafeMapping.Add("HIREDATE", typeof(string)); // Map EMPNO to a string // If the column name in the EMP table is case-sensitive, // the safe type mapping column name must also be case-sensitive. adapter.SafeMapping.Add("EMPNO", typeof(string)); adapter.SafeMapping.Add("SAL", typeof(string)); // Create and fill the DataSet using the EMP DataSet dataset = new DataSet(); adapter.Fill(dataset, "EMP"); // Get the EMP table from the dataset DataTable table = dataset.Tables["EMP"]; // Get the first row from the EMP table DataRow row = table.Rows[0]; // Print out the row info Console.WriteLine("EMPNO Column: type = " + row["EMPNO"].GetType() + "; value = " + row["EMPNO"]); Console.WriteLine("ENAME Column: type = " + row["ENAME"].GetType() + "; value = " + row["ENAME"]); Console.WriteLine("HIREDATE Column: type = " + row["HIREDATE"].GetType()+ "; value = " + row["HIREDATE"]); Console.WriteLine("SAL Column: type = " + row["SAL"].GetType() + "; value = " + row["SAL"]); } }
See Also: