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 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
に基づいて、そのプロバイダ用の適切なファクトリを取得できます。これにより、接続文字列を簡単に管理および変更できます。さらに、これによって接続文字列への文字列注入に対してより優れたセキュリティを提供します。
ODP.NETでは、OraclePermission
クラスを使用してコード・アクセス・セキュリティを実装します。これにより、データベースにアクセスするアプリケーション・コードに、アクセスに必要な権限が付与されます。
.NETアセンブリからODP.NETを介してOracle Databaseへのアクセスが試行されると、ODP.NETによってOraclePermission
が要求されます。.NETランタイム・セキュリティ・システムにより、コール・アセンブリと、コール・スタックにあるその他すべてのアセンブリにOraclePermission
が付与されているかどうかが確認されます。コール・スタックのすべてのアセンブリにOraclePermission
が付与されている場合、コール・アセンブリからデータベースへのアクセスが可能になります。コール・スタックのアセンブリのいずれかにOraclePermission
が付与されていない場合、セキュリティ例外がスローされます。
DemandOraclePermission
構成属性は、ODP.NET APIのOraclePermission
要求を有効化および無効化するために使用されます。DemandOraclePermission
の値は、Windowsレジストリまたは個々のアプリケーション構成ファイルで指定できます。
DemandOraclePermission
構成属性を構成するには、次のWindowsレジストリ・キーを使用します。
HKEY_LOCAL_MACHINE\SOFTWARE\ORACLE\ODP.NET\Assembly_Version\DemandOraclePermission
Assembly_Version
は、Oracle.DataAccess.dll
の完全なアセンブリ・バージョン番号です。DemandOraclePermission
キーの種類はREG_SZ
です。1
(有効)または0
(無効)に設定できます。
また、アプリケーションの構成ファイルを使用して、各アプリケーションのOraclePermission
要求を有効化することもできます。次の例では、アプリケーション構成ファイルでDemandOraclePermission
プロパティを有効化しています。
<configuration> <oracle.dataaccess.client> <settings> <add name="DemandOraclePermission" value="1"/> </settings> </oracle.dataaccess.client> </configuration>
アセンブリのコード・グループに関連付けられている権限セットにOraclePermission
が追加されていると、アプリケーションまたはアセンブリが正常にデータベースにアクセスできます。システム管理者は、Microsoft .NET構成ツール(Mscorcfg.msc
)または手動で該当の権限セットを変更できます。
また、管理者はコード・アクセス・セキュリティ・ポリシー・ツール(Caspol.exe
)などの適切な.NET Frameworkツールを使用して、マシン、ユーザーおよびエンタープライズ・レベルでOraclePermission
を含めるようにセキュリティ・ポリシーを変更することもできます。
DemandOraclePermission
構成属性を使用してOraclePermission
要求が有効化されている場合、OracleConnection
でOraclePermission
オブジェクトを使用してセキュリティ要求が作成されます。アプリケーション開発者は、OracleConnection
を使用する前に、これらのコードに十分な権限があることを確認する必要があります。
高または中より低い信頼レベルで実行されているWebアプリケーションの場合、アプリケーションでセキュリティ・エラーが発生しないように、適切なweb_
TrustLevel
.config
ファイルにOraclePermission
を構成する必要があります。
OraclePermission
は、OracProvCfg
ツールを使用して構成できます。OraProvCfg.exe
によって、指定した.NET frameworkバージョンに関連付けられているweb_hightrust.config
およびweb_mediumtrust.config
ファイルに適切なエントリが追加されます。次の例では、.NET 2.0 WebアプリケーションでOraclePermission
を構成するために、OraProvCfg
ツールを使用する方法が示されています。
OraProvCfg.exe /action:config /product:odp /component:oraclepermission
/frameworkversion:v2.0.50727
/providerpath:full_path_of_Oracle.DataAccess.dll
前述のコマンドを実行すると、次のエントリが、ASP.NET権限セットのweb_hightrust.config
およびweb_mediumtrust.config
ファイルに追加されます。
<IPermission class="Oracle.DataAccess.Client.OraclePermission, Oracle.DataAccess, Version=2.112.2.0, Culture=neutral, PublicKeyToken=89b483f429c47342" version="1" Unrestricted="true" />
また、必要に応じて、OraProvCfg
を使用して、.config
ファイルからこれらのエントリを削除できます。次の例では、この方法が示されています。
OraProvCfg.exe /action:unconfig /product:odp /component:oraclepermission
/frameworkversion:v2.0.50727
/providerpath:full_path_of_Oracle.DataAccess.dll
部分信頼環境で実行されるWindowsアプリケーションの場合、security.config
ファイルの適切な権限セットにOraclePermission
エントリを指定する必要があります。security.config
ファイルは、%windir%\Microsoft.NET\Framework\
{version}
\CONFIG
フォルダにあります。
次の例では、.NET 2.0 Windowsアプリケーション用のOraclePermission
エントリが指定されています。
<IPermission class="Oracle.DataAccess.Client.OraclePermission, Oracle.DataAccess, Version=2.112.2.0, Culture=neutral, PublicKeyToken=89b483f429c47342" version="1" Unrestricted="true" />
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
をサポートしています。Oracle Database 11gリリース(11.1)以上のSystem.Transactions
スコープでオープンされた最初の接続に対しては、ローカル・トランザクションが作成されます。2番目の接続がオープンされると、このトランザクションは自動的に分散トランザクションに昇格します。この機能は、パフォーマンスとスケーラビリティの向上を実現します。
TransactionScope
やServicedComponent
などのトランザクション・コンテキスト内で作成された接続は、様々なリリースのOracle Databaseに対して確立できます。ただし、ローカル・トランザクションを昇格できるようにするには、次の条件を満たす必要があります。
Oracle Database 11gリリース1(11.1)以上のインスタンスに対してトランザクション・コンテキストの最初の接続を確立する必要があります。
トランザクション・コンテキスト内でオープンになっているすべての接続のPromotable Transaction
設定がpromotable
に設定されている必要があります。Promotable Transaction
設定がlocal
に設定されている場合、同じトランザクション・コンテキスト内にある後続の接続をオープンしようとすると、例外がスローされます。
ローカル・トランザクションの昇格には11.1.0.7.20以上のOracle Services for Microsoft Transaction Serverが必要です。この要件を満たしていない場合、同じトランザクション・コンテキスト内にある2番目の接続要求で例外がスローされます。
レジストリ、構成ファイル(マシン、Web、アプリケーション)またはPromotable Transaction
接続文字列属性で、PromotableTransaction
の値としてlocal
を設定すると、ローカル・トランザクションに関連付けられているトランザクション・コンテキスト内でオープンできる接続は1つのみになります。このようなローカル・トランザクションは昇格できません。
Oracle Database 11gリリース1(11.1)より前のインスタンスに接続するアプリケーションについては、「旧リリースのデータベースにおけるローカル・トランザクション・サポート」を参照してください。この項では、Promotable Transactionの設定を使用してODP.NETの動作を制御する方法について説明します。
アプリケーションがSystem.Transactions
を使用する場合は、"enlist"
接続文字列属性を"true"
(デフォルト)または"dynamic"
のいずれかに設定する必要があります。
ODP.NETは、分散トランザクションを使用するアプリケーション用に、次のSystem.Transactions
プログラミング・モデルをサポートしています。
TransactionScope
クラスは、トランザクションに明示的に登録する必要のないトランザクション・アプリケーションを記述するためのメカニズムを提供します。これを実現するには、アプリケーションでTransactionScope
オブジェクトを使用して、トランザクション・コードを定義します。このトランザクション・スコープ内で作成された接続は、分散トランザクションへの昇格が可能なローカル・トランザクションに登録されます。
注意: デフォルトでは、最初の接続がOracle Database 11gリリース1(11.1)より前のインスタンスに対してオープンされた場合、その接続は分散トランザクションとして登録されます。 「旧リリースのデータベースにおけるローカル・トランザクション・サポート」で説明する手順を使用して、トランザクションをローカル・トランザクションとして作成することも可能です。ただし、その場合のトランザクションは分散トランザクションに昇格できません。 |
変更をコミットするには、アプリケーションで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 promotable local 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); } } }
TransactionScope
内の最初の接続がOracle Database 11gリリース1(11.1)より前のインスタンスに対してオープンされた場合、デフォルトでは分散トランザクションが作成されます。この項で説明する手順を使用すれば、最初の接続でローカル・トランザクションを作成することもできます。
System.Transactions
スコープ内にローカル・トランザクションを作成するには、レジストリ、マシン/Web/アプリケーション構成ファイルまたはPromotable Transaction
接続文字列属性のPromotableTransaction
設定を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 Databaseを更新する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と類似していますが異なります)。ダイレクト・パス・ロードを使用すると、SQL INSERT
文を使用する従来のロードより早く処理できます。従来のロードでは、Oracleのデータ・ブロックをフォーマットしてデータ・ブロックをデータ・ファイルに直接書き込みます。一括コピーにより、処理中のオーバーヘッドが大幅に削減されます。
ODP.NETの一括コピー機能では旧リリースのOracle Databaseにデータをロードできます。
ODP.NETの一括コピー機能は、次の項で説明するように、ダイレクト・パス・ロードと同一の基本制限および整合性制約に従います。
一括コピーでサポートされているデータ型は次のとおりです。
ORA_SB4
ORA_VARNUM
ORA_FLOAT
ORA_CHARN
ORA_RAW
ORA_BFLOAT
ORA_BDOUBLE
ORA_IBDOUBLE
ORA_IBFLOAT
ORA_DATE
ORA_TIMESTAMP
ORA_TIMESTAMP_TZ
ORA_TIMESTAMP_LTZ
ORA_INTERVAL_DS
ORA_INTERVAL_YM
一括コピーでは上書きはサポートされていません。
パーティションを含む表には、表で定義済のグローバル索引を含めることはできません。
パーティションがメンバーの表には、有効な参照制約およびチェック制約を含めることはできません。
有効なトリガーは使用できません。
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つでもエラーがあると、再使用できません。
整合性制約とは異なり、挿入トリガーは使用可能に戻っても表全体に対して再び適用されません。つまり、ダイレクト・パスでロードされた行に対しては、挿入トリガーは起動しません。ダイレクト・パスを使用する際には、挿入トリガーに関連するすべての動作が新しい行に対して実行されることを確認する必要があります。