Oracle Data Provider for .NET 10.2.0.2以降は、Microsoft ADO.NET 2.0 APIをサポートします。
この項の内容は次のとおりです。
ADO.NET 2.0はMicrosoft社仕様であり、プロバイダの主体性、コンポーネントの再利用拡大およびアプリケーションの互換性に対して、共同で作業するために設計されたデータ・アクセス機能を提供します。追加の機能により、アプリケーションでデータ・ソース、スキーマおよびプロバイダに関する情報の動的な検索が簡単にできます。
|
注意: Microsoft ADO.NET 2.0とともにODP.NETを使用するには、ADO.NET 2.0準拠のODP.NETが必要です。 |
|
関連項目: MSDNライブラリ内のADO.NET |
プロバイダ主体の汎用データ・アクセス・コードを記述するため、ADO.NET 1.xはインタフェースを使用します。同じ目的で、ADO.NET 2.0は、下位互換性のためADO.NET 1.xからのインタフェースを保持しながら、継承ベースのアプローチも提供します。
ODP.NET for ADO.NET 2.0では下位互換性がサポートされているため、ADO.NET 1.x APIsも使用できます。
このガイドでは、適切な場合はADO.NET 2.0およびADO.NET 1.x両方に対する宣言も提供します。
ADO.NET 2.0では、データ・クラスはSystem.Data.Commonネームスペースで定義されたベース・クラスから導出されます。開発者は、プロバイダ・ファクトリ・クラスを使用して、これらのベース・クラスのプロバイダ固有のインスタンスを作成できます。
プロバイダ・ファクトリ・クラスでは、汎用データ・アクセス・コードによって、最小限のデータ・ソース固有コードで複数のデータ・ソースへアクセスできます。これにより、複数のデータ・ソースにアクセスするアプリケーションで現在使用されている条件付きロジックの多くを削減できます。
Oracle Data Provider for .NETを使用すると、OracleClientFactoryクラスを戻し、インスタンス化できます。これにより、ベース・クラスを継承する次のODP.NETクラスのインスタンスを作成するアプリケーションが有効になります。
表3-3 ADO.NET 2.0ベース・クラスを継承するODP.NETクラス
| ODP.NETクラス | ADO.NET 2.0ベース・クラスから継承 |
|---|---|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
一般に、アプリケーションはいまだOracle固有の接続文字列、SQLまたはストアド・プロシージャ・コールを必要としており、Oracle.DataAccess.Clientからのファクトリを使用することを宣言します。
OracleConnectionStringBuilderクラスでは、エラーを起こしにくく、管理しやすい接続文字列を作成します。
このクラスを使用することによって、開発者は設定ファイルを使用した接続文字列の提供およびキー/値ペアによる動的な値の設定が可能です。設定ファイル・エントリの例は次のとおりです。
<configuration>
<connectionStrings>
<add name="Publications" providerName="Oracle.DataAccess.Client"
connectionString="User Id=scott;Password=tiger;Data Source=inst1" />
</connectionStrings>
</configuration>
接続文字列情報は、接続文字列名を指定して取得できます。この例ではPublicationsです。次に、providerNameに基づいて、そのプロバイダ用の適切なファクトリを取得できます。これにより、接続文字列を簡単に管理および変更できます。さらに、これによって接続文字列への文字列注入に対してより優れたセキュリティを提供します。
ADO.NET 2.0では、OracleConnection.GetSchema APIから5つの異なるタイプのメタデータ・コレクションが公開されています。これにより、アプリケーション開発者は、すべてのOracleデータ・ソースに対して、メタデータの取得を個別のアプリケーション・ベースでカスタマイズできます。このようにして、開発者は複数のデータ・ソースからのメタデータを管理する汎用セットのコードをビルドできます。
公開されているメタデータのタイプは次のとおりです。
MetaDataCollections
テーブル、列、インデックスおよびストアド・プロシージャなどのデータ・ソースから使用できるメタデータ・コレクションのリストです。
Restrictions
要求されたスキーマ情報の範囲を制限して、各メタデータ・コレクションに適用される制限。
DataSourceInformation
製品名やバージョンなど、現在使用されているデータベースのインスタンスについての情報。
DataTypes
データベースがサポートする各データ型についての情報のセット。
ReservedWords
Oracle問合せ言語の予約語。
ODP.NETでは、データベース・スキーマ情報の包括的なセットが提供されています。開発者は、個々のアプリケーション・ベースでGetSchemaメソッドが戻すメタデータを拡張またはカスタマイズできます。
これを行うには、開発者はカスタマイズしたメタデータ・ファイルを作成し、アプリケーションにファイル名を提供する必要があります。方法は次のとおりです。
カスタマイズしたメタデータ・ファイルを作成し、それを.NET FrameworkがインストールされたCONFIGサブディレクトリに置きます。これは、machine.configおよびセキュリティ設定があるディレクトリです。
このファイルには、変更のみではなく、スキーマ設定情報のセット全体を含める必要があります。開発者は、ユーザー固有の要件を検索するスキーマ動作の変更を提供します。たとえば、開発者は内部データベース表にフィルタをかけ、ユーザー固有の表のみを検索できます。
次と同じく、アプリケーションのapp.configファイル内にエントリを追加し、メタデータ・ファイルの名前を名前/値ペアの書式で指定します。
<oracle.dataaccess.client>
<settings>
<add name="MetaDataXml" value="CustomMetaData.xml" />
</settings>
</oracle.dataaccess.client>
GetSchemaメソッドがコールされると、ODP.NETではapp.configファイルでカスタマイズしたメタデータXMLファイルの名前を確認します。最初に、GetSchemaメソッドはプロバイダにちなんで付けられた要素、この例ではoracle.dataaccess.clientでファイル内のエントリを検索します。このXML要素内の名前MetaDataXmlに対応する値は、カスタマイズしたXMLファイルの名前で、この例ではCustomMetaData.xmlです。
メタデータ・ファイルが正しいディレクトリ内にない場合、アプリケーションは、ODP.NETに含まれているデフォルトのメタデータXMLファイルをロードします。
ODP.NET for .NET Framework 2.0は、System.Transactionsをサポートします。System.Transactionsが使用されると、トランザクションは、「System.Transactionsサポートのローカル・トランザクション」で説明されているように、ローカル・トランザクションとして作成されるように指定されている場合を除き、(デフォルトで)すぐに分散トランザクションになります。
アプリケーションがSystem.Transactionsを使用する場合は、"enlist"接続文字列属性を"true"(デフォルト)または"dynamic"のいずれかに設定する必要があります。
ODP.NETは、分散トランザクションを使用するアプリケーション用に、次のSystem.Transactionsプログラミング・モデルをサポートしています。
TransactionScopeクラスでは、分散トランザクションに明示的に登録する必要のないトランザクション・アプリケーションを記述する方法が提供されます。これを行うには、アプリケーションでTransactionScopeオブジェクトを使用して、トランザクション・コードを定義します。このトランザクション範囲内で作成された接続は分散トランザクションに登録されます。変更をコミットするには、アプリケーションでTransactionScopeオブジェクトに対してCompleteメソッドをコールする必要があります。コールしない場合、トランザクションはデフォルトで強制終了します。
// C#
using System;
using Oracle.DataAccess.Client;
using System.Data;
using System.Data.Common;
using System.Transactions;
class psfTxnScope
{
static void Main()
{
int retVal = 0;
string providerName = "Oracle.DataAccess.Client";
string constr =
@"User Id=scott;Password=tiger;Data Source=oracle;enlist=true";
// Get the provider factory.
DbProviderFactory factory = DbProviderFactories.GetFactory(providerName);
try
{
// Create a TransactionScope object, (It will start an ambient
// transaction automatically).
using (TransactionScope scope = new TransactionScope())
{
// Create first connection object.
using (DbConnection conn1 = factory.CreateConnection())
{
// Set connection string and open the connection. this connection
// will be automatically enlisted in a distributed transaction.
conn1.ConnectionString = constr;
conn1.Open();
// Create a command to execute the sql statement.
DbCommand cmd1 = factory.CreateCommand();
cmd1.Connection = conn1;
cmd1.CommandText = @"insert into emp (empno, ename, job) values
(1234, 'emp1', 'dev1')";
// Execute the SQL statement to insert one row in DB.
retVal = cmd1.ExecuteNonQuery();
Console.WriteLine("Rows to be affected by cmd1: {0}", retVal);
// Close the connection and dispose the command object.
conn1.Close();
conn1.Dispose();
cmd1.Dispose();
}
// The Complete method commits the transaction. If an exception has
// been thrown or Complete is not called then the transaction is
// rolled back.
scope.Complete();
}
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
Console.WriteLine(ex.StackTrace);
}
}
}
CommittableTransactionオブジェクトとEnlistTransactionメソッドのインスタンス化によって、接続を明示的に作成して分散トランザクションに登録できます。アプリケーションでは、CommittableTransactionオブジェクトに対してCommitまたはRollbackをコールする必要があります。
// C#
using System;
using Oracle.DataAccess.Client;
using System.Data;
using System.Data.Common;
using System.Transactions;
class psfEnlistTransaction
{
static void Main()
{
int retVal = 0;
string providerName = "Oracle.DataAccess.Client";
string constr =
@"User Id=scott;Password=tiger;Data Source=oracle;enlist=dynamic";
// Get the provider factory.
DbProviderFactory factory = DbProviderFactories.GetFactory(providerName);
try
{
// Create a committable transaction object.
CommittableTransaction cmtTx = new CommittableTransaction();
// Open a connection to the DB.
DbConnection conn1 = factory.CreateConnection();
conn1.ConnectionString = constr;
conn1.Open();
// enlist the connection with the commitable transaction.
conn1.EnlistTransaction(cmtTx);
// Create a command to execute the sql statement.
DbCommand cmd1 = factory.CreateCommand();
cmd1.Connection = conn1;
cmd1.CommandText = @"insert into emp (empno, ename, job) values
(1234, 'emp1', 'dev1')";
// Execute the SQL statement to insert one row in DB.
retVal = cmd1.ExecuteNonQuery();
Console.WriteLine("Rows to be affected by cmd1: {0}", retVal);
// commit/rollback the transaction.
cmtTx.Commit(); // commits the txn.
//cmtTx.Rollback(); // rolls back the txn.
// close and dispose the connection
conn1.Close();
conn1.Dispose();
cmd1.Dispose();
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
Console.WriteLine(ex.StackTrace);
}
}
}
Oracle Data Provider for .NETリリース10.2.0.3以降のアプリケーションは、System.Transactionsとともにローカル・トランザクションを使用できます。ODP.NETの以前のバージョンでは、System.Transactionsを使用した分散トランザクションのみサポートされていました。
ローカル・トランザクションを使用するには、PromotableTransactionレジストリ・エントリを作成して"local"に設定するか、"Promotable Transaction"接続文字列属性を"local"に設定する必要があります。
"local"が指定されている場合、TransactionScopeでオープンした最初の接続ではローカル・トランザクションが使用されます。後続の接続が同じTransactionScopeでオープンされると例外がスローされます。TransactionScopeですでに接続がオープンしていて、"Promotable Transaction=local"のOracleConnectionが同じTransactionScope内でオープンされようとしている場合は例外がスローされます。
"promotable"が指定されている場合、同じTransactionScopeでオープンされる最初と後続の接続は、同じ分散トランザクション内で登録されます。
レジストリと接続文字列属性の両方が使用されていて異なる値に設定されている場合、接続文字列属性はレジストリ・エントリの値をオーバーライドします。どちらも設定されていない場合は"promotable"が使用されます。これはデフォルトの値で、分散トランザクションのみがサポートされているODP.NETの以前のバージョンと同じです。
ODP.NETの特定のバージョンに対するレジストリ・エントリは、ODP.NETのバージョンを使用するすべてのアプリケーションに適用します。
OracleDataAdapter.Updateメソッドがコールされると、OracleDataAdapter UpdateBatchSizeプロパティではバッチ処理が有効になります。UpdateBatchSizeは、各ラウンドトリップで、Oracleデータベースを更新するDataSet行数を示す数値プロパティです。
これにより、開発者はデータベースへのラウンド・トリップの回数を削減できます。
|
注意: Microsoft社の必要なホットフィックスMicrosoft ADO.NET 2.0には この問題を解決するには、ODP.NETリリース11.1とMicrosoft社の特定のホットフィックスの両方を同じコンピュータにインストールする必要があります。Microsoft社のホットフィックスは、 このフィックスがないと、 ODP.NETは、このホットフィックスを使用して、バッチ内で失敗した個々の行の |
ADO.NET 2.0専用であるクラスに加えて、System.Data.Commonネームスペースから継承する他のODP.NETクラスには、ADO.NET 2.0を必要とするメソッドとプロパティが含まれています。
次のクラスはADO.NET 2.0専用です。
次のクラス・メンバーはADO.NET 2.0専用です。
OracleCommandBuilderクラス・メンバー
CatalogLocationプロパティ(サポート対象外)
CatalogSeparatorプロパティ(サポート対象外)
ConflictOptionプロパティ(サポート対象外)
QuotePrefixプロパティ
QuoteSuffixプロパティ
SchemaSeparatorプロパティ
QuoteIdentifierメソッド
OracleConnectionクラス・メンバー
GetSchemaメソッド
OracleDataAdapterクラス・メンバー
UpdateBatchSizeプロパティ
OracleDataReaderクラス・メンバー
OracleParameterクラス・メンバー
ResetDbTypeメソッド
OracleParameterCollectionクラス・メンバー
AddRangeメソッド
ODP.NETは、アプリケーションが1つのデータベースの表から同一または異なるデータベースの表へ大量のデータを効率よくロードできる一括コピー機能を提供します。
ODP.NETの一括コピー機能では、ダイレクト・パス・ロード方法を使用します(これはOracle SQL*Loaderと類似していますが異なります)。ダイレクト・パス・ロードを使用すると、Oracleのデータ・ブロックをフォーマットしてデータ・ファイルに直接データ・ブロックを書き込むため、SQL INSERT文を使用する従来のロードより早く処理できます。これにより処理中のオーバーヘッドが大幅に削減されます。
ODP.NETの一括コピー機能では、9iリリース2、10gリリース1、10gリリース2および11gリリース1データベースにデータをロードできます。
ODP.NETの一括コピー機能は、次の項で説明するように、ダイレクト・パス・ロードと同一の基本制限および整合性制約に従います。
パーティションを含む表には、表で定義済のグローバル索引を含めることはできません。
パーティションがメンバーの表には、有効な参照制約およびチェック制約を含めることはできません。
有効なトリガーは使用できません。
Oracle一括コピー中、次の場合にいくつかの整合性制約は自動的に有効または無効になります。
有効となる制約
Oracle一括コピー中、次の制約はデフォルトで自動的に有効になります。
NOT NULL
UNIQUE
PRIMARY KEY(非NULL列での一意制約)
NOT NULL制約は列配列の作成時にチェックされます。NOT NULL制約に違反する行はすべて拒否されます。
UNIQUE制約はロードの最後で索引が再構築されるときに検証されます。この索引はUNIQUE制約に違反すると、索引使用禁止状態のままになります。
無効となる制約
Oracle一括コピー中、次の制約はデフォルトで自動的に無効になります。
CHECK制約
参照制約(FOREIGN KEY)
EVALUATE CHECK_CONSTRAINTS句を指定する場合、CHECK制約は自動的には無効になりません。CHECK制約はダイレクト・パス・ロード中に評価され、CHECK制約に違反する行はすべて拒否されます。
ダイレクト・パス・ロードが始まると、表挿入トリガーも使用禁止になります。行がロードされ索引が再構築されると、使用禁止となっていたすべてのトリガーは自動的に再び使用可能になります。ログ・ファイルには、ロード時に使用禁止となっていたトリガーがすべてリストされます。トリガーを使用可能に戻すときに1つでもエラーがあると、再使用できません。
整合性制約とは異なり、挿入トリガーは使用可能に戻っても表全体に対して再び適用されません。つまり、ダイレクト・パスでロードされた行に対しては、挿入トリガーは起動しません。ダイレクト・パスを使用する際には、挿入トリガーに関連するすべての動作が新しい行に対して実行されることを確認する必要があります。