次に示すOracleデータ型がDataSetで近似の.NETタイプに変換された場合にデータが失われる可能性があるため、ODP.NETのOracleDataAdapterクラスではSafeタイプ・マッピング機能を提供しています。
NUMBER
DATE
TimeStamp(すべてのTimeStampオブジェクトが対象)
INTERVAL DAY TO SECOND
この項の内容は次のとおりです。
次の項では、Oracleデータ型と対応する.NETタイプとの違いの詳細を説明します。一般に、Oracleデータ型は.NETタイプより優れた精度を持っています。
Oracle NUMBER型から.NET Decimalタイプへの変換
Oracleデータ型NUMBERでは最大38までの精度を保持できますが、.NET Decimalタイプでは最大28までの精度を保持できます。28より大きい精度のNUMBERデータ型が.NET Decimalタイプに取り出された場合は、精度が失われます。
表3-26は、Oracle NUMBERおよび.NET Decimalタイプの最大値と最小値のリストです。
表3-26 Oracle NUMBERと.NET Decimalとの比較
| 限界値 | Oracle NUMBER | .NET Decimal |
|---|---|---|
|
最大値 |
9.9999999999999999999999999999999999999 e125 |
79,228,162,514,264,337,593,543,950,335 |
|
最小値 |
-9.9999999999999999999999999999999999999 e125 |
-79,228,162,514,264,337,593,543,950,335 |
Oracle Date型から.NET DateTimeタイプへの変換
Oracleデータ型DATEでは紀元前の日付を表すことができますが、.NET DateTimeタイプでは表せません。紀元前を示すDATEが.NET DateTimeタイプに取り出された場合は、データが失われます。
表3-27は、Oracle Dateおよび.NET DateTimeタイプの最大値と最小値のリストです。
表3-27 Oracle Dateと.NET DateTimeとの比較
| 限界値 | Oracle Date | .NET DateTime |
|---|---|---|
|
最大値 |
西暦9999年12月31日 |
西暦9999年12月31日23時59分59.9999999秒 |
|
最小値 |
紀元前4712年1月1日 |
西暦1年1月1日00時00分00.0000000秒 |
Oracle TimeStamp型から.NET DateTimeタイプへの変換
DATEデータ型と同様に、Oracleデータ型TimeStampでは紀元前の日付を表すことができますが、.NET DateTimeタイプでは表せません。紀元前を示すTimeStampが.NET DateTimeタイプに取り出された場合は、データが失われます。Oracle TimeStamp型はeの-9乗の単位で値を表すことができますが、.NET DateTimeタイプではeの-7乗の単位でしか値を表せません。Oracleのタイムゾーン付きTimeStampデータ型ではタイムゾーン情報を格納できますが、.NET DateTimeでは格納できません。
表3-28は、Oracle TimeStampおよび.NET DateTimeタイプの最大値と最小値のリストです。
表3-28 Oracle TimeStampと.NET DateTimeとの比較
| 限界値 | Oracle TimeStamp | .NET DateTime |
|---|---|---|
|
最大値 |
西暦9999年12月31日23時59分59.999999999秒 |
西暦9999年12月31日23時59分59.9999999秒 |
|
最小値 |
紀元前4712年1月1日00時00分00.000000000秒 |
西暦1年1月1日00時00分00.0000000秒 |
Oracle INTERVAL DAY TO SECONDから.NET TimeSpanへの変換
Oracleデータ型INTERVAL DAY TO SECONDでは、最大9までの精度を保持でき、.NET TimeSpanタイプは最大7までの精度を保持できます。7より大きい精度のINTERVAL DAY TO SECONDデータ型が.NET TimeSpanタイプに取り出された場合は、精度が失われます。Oracle INTERVAL DAY TO SECONDではeの-9乗の単位で値を表すことができますが、.NET TimeSpanではeの-7乗の単位でしか値を表せません。
表3-29は、Oracle INTERVAL DAY TO SECONDおよび.NET DateTimeタイプの最大値と最小値のリストです。
OracleDataAdapter Safeタイプ・マッピング機能により、これらのタイプのいずれかのOracleデータが.NET DataSetへ移入された場合のデータの消失を防ぎます。SafeMappingプロパティを適切に設定することにより、このような型を次のいずれかとしてDataSet内で安全に表すことができます。
.NET byte[](Oracle書式)
.NET String
Safeタイプ・マッピングはデフォルトでは無効です。
Safeタイプ・マッピング機能を使用するには、キーと値のペアのハッシュ・テーブルを使用してOracleDataAdapter.SafeMappingプロパティを設定する必要があります。キーと値のペアでは、データベース表の列名(string型)を.NETタイプ(Type型)にマップする必要があります。ODP.NETはbyte[]型およびString型へのSafeタイプ・マッピングをサポートします。これ以外のタイプ・マッピングでは、例外が発生します。
設計時に列名が不明な場合は、アスタリスク(*)を使用すると、データベース型のすべての出現を安全な.NETタイプにマップできます。有効な列名とアスタリスクが両方ある場合は、列名が使用されます。
|
注意:
|
StringとしてのSafeタイプ・マッピングは判断しやすいため、それ以上の変換は不要です。Oracleデータ型の中にはStringへの変換時にさらに変換が必要になるものがあり、その場合はbyte[]への変換よりも時間がかかります。.NET文字列からODP.NETタイプに戻す場合は、セッションの書式情報に依存します。
Safeタイプの例
// 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"]);
}
}