OracleDataAdapter Safeタイプ・マッピング
次に示すOracleデータ型がDataSet
で近似の.NETタイプに変換された場合にデータが失われる可能性があるため、ODP.NETのOracleDataAdapter
クラスではSafeタイプ・マッピング機能を提供しています。
-
NUMBER
-
DATE
-
TimeStamp
(すべてのTimeStamp
オブジェクトが対象) -
INTERVAL
DAY
TO
SECOND
注意:
ODP.NET管理対象ドライバおよびODP.NETでは、Safeタイプ・マッピングはサポートされていません。
この項の内容は次のとおりです。
Oracleデータ型と.NETタイプとの比較
次の項では、Oracleデータ型と対応する.NETタイプとの違いの詳細を説明します。一般に、Oracleデータ型は.NETタイプより優れた精度を持っています。
Oracle NUMBER型から.NET Decimalタイプへの変換
Oracleデータ型NUMBER
では最大38までの精度を保持できますが、.NET Decimal
タイプでは最大28までの精度を保持できます。28より大きい精度のNUMBER
データ型が.NET Decimal
タイプに取り出された場合は、精度が失われます。
表3-28は、Oracle NUMBER
および.NET Decimal
タイプの最大値と最小値のリストです。
表3-28 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-29は、Oracle Date
および.NET DateTime
タイプの最大値と最小値のリストです。
表3-29 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-30は、Oracle TimeStamp
および.NET DateTime
タイプの最大値と最小値のリストです。
表3-30 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-31は、Oracle INTERVAL
DAY
TO
SECOND
および.NET DateTime
タイプの最大値と最小値のリストです。
表3-31 Oracle INTERVAL DAY TO SECONDと.NET TimeSpanとの比較
限界値 | Oracle INTERVAL DAY TO SECOND | .NET TmeSpan |
---|---|---|
最大値 |
+999999999 23:59:59.999999999 |
+10675199 02:48:05.4775807 |
最小値 |
-999999999 23:59:59.999999999 |
-10675199 02:48:05.4775808 |
SafeMappingプロパティ
OracleDataAdapter
Safeタイプ・マッピング機能により、これらのタイプのいずれかのOracleデータが.NET DataSet
へ移入された場合のデータの消失を防ぎます。SafeMapping
プロパティを適切に設定することにより、このような型を次のいずれかとしてDataSet
内で安全に表すことができます。
-
.NET
byte[]
(Oracle書式) -
.NET
String
Safeタイプ・マッピングはデフォルトでは無効です。
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"]); } }
関連項目: