この章では、Oracle Objects for OLE(OO4O)のチューニング、問題解決およびエラー処理について説明します。
内容は次のとおりです。
次の各項は、Oracle Objects for OLEを使用するアプリケーションのパフォーマンス・チューニングに役立ちます。
この項の内容は次のとおりです。
Early Binding技法によって、OO4Oオブジェクトは(Visual Basicが提供する汎用的なオブジェクト型ではなく)本来のオブジェクト型に厳密に型変換されます。これらのオブジェクトは、後でOO4Oオブジェクトとして再分類された汎用的なオブジェクトとしてではなく、OO4Oオブジェクトとして直接宣言されます。Early Binding技法によってOO4Oのタイプ・ライブラリへの頻繁なアクセスが削減されるため、パフォーマンスが向上します。次に、例を示します。
'Early binding of OO4O objects Dim OraSession as OraSession Dim OraDatabase as OraDatabase Dim OraDynaset as OraDynaset 'Generic binding of OO4O objects Dim OraSession as Object Dim OraDatabase as Object Dim OraDynaset as Object
OO4OオブジェクトのEarly Bindingを使用するには、Visual BasicプロジェクトのOracleインプロセス・サーバー・タイプ・ライブラリを参照する必要があります。
データ・アクセスは、ダイナセットのキャッシュ・パラメータとフェッチ・パラメータを変更することによって、チューニングおよびカスタマイズできます。FetchLimit
パラメータを高い値に設定すると、各要求でフェッチされる行数が増えるため、Oracle Databaseへのネットワーク・トリップの回数が減少し、結果的にパフォーマンスが向上します。
FetchLimit
パラメータのサイズを大きくすることによる弊害は、クライアント側のメモリーの必要量が増加すること、およびディスク上の一時キャッシュ・ファイルでのスワップ・データが増加することです。FetchLimit
の値は、クライアント・コンピュータの構成と予測される問合せ結果のサイズに合わせて適切に設定する必要があります。
FetchLimit
の値は、次の方法で設定できます。
CreateCustomDynaset
メソッドを使用する方法
WindowsレジストリにあるOO4Oエントリのパラメータを変更する方法
Windowsでは、レジストリ・キーはHKEY_LOCAL_MACHINE
、サブキーはsoftware\oracle\
KEY_
HOMENAME
\oo4o
です(ここで、HOMENAME
は適切なOracleホームです)。OO4Oをインストールすると、次のようなセクションがレジストリに作成されます。
"FetchLimit" = 100
不要なオブジェクト参照を使用した不適切なコーディング技法は、パフォーマンスに影響を与えます。ダイナセット・オブジェクトのナビゲーションでは、OraFields
コレクションとOraField
オブジェクトへの参照数を少なくしてください。次のコードは、効率的でない例です。
'Create the OraDynaset Object Set OraDynaset = OraDatabase.CreateDynaset("select * from emp", 0&) 'Traverse until EOF is reached Do Until OraDynaset.EOF msgbox OraDynaset.Fields("sal").value OraDynaset.MoveNext Loop
このコードでは、OraDynaset
コレクション、OraFields
コレクションおよびOraField
オブジェクトがループのたびに参照されます。OO4Oではフィールド・コレクション・オブジェクトに関する処理が改善されていますが、オートメーション・オブジェクトへの複数の参照は、基礎となるOLE/COMオートメーションのレイヤーを介しているため、実行が遅れます。
次の例では、ダイナセットのフィールド・コレクションではなく、フィールド・オブジェクトを介してフィールドを参照する方法を示しています。テストでは、この少量の追加コードによってパフォーマンスが大幅に向上することが確認されています。
Dim flds() As OraField Dim i, fldcount As Integer ' Create the OraDynaset Object Set OraDynaset = OraDatabase.CreateDynaset("select * from emp", 0&) ' Get the field count, and output the names fldcount = OraDynaset.Fields.Count ReDim flds(0 To fldcount - 1) For i = 0 To fldcount - 1 Set flds(i) = OraDynaset.Fields(i) Next I 'Traverse until EOF is reached Do Until OraDynaset.EOF msgbox Flds(5).Value msgbox Flds(6).Value OraDynaset.MoveNext Loop
複数のオブジェクトを介して参照されるメソッドまたはオブジェクトは非効率な場合がありますが、それを回避するためのコードの追加は、必ずしも確実に時間が節約されるとはかぎりません。フィールド参照は複数回発生する可能性が高いことから、最初はフィールド参照から着手することが効果的です。
OO4Oは、SQL文の処理時に、パラメータ・オブジェクトのバインドを有効および無効にする方法を提供します。この方法は、OraParameter
オブジェクトのAutoBindDisable
とAutoBindEnable
メソッドを介して実行されます。SQL文にパラメータ名が含まれていない場合は、OraParameter
オブジェクトを無効にすることでパラメータ・オブジェクトへの不要な参照を回避できます。この方法は、主にPL/SQLプロシージャで記述されたアプリケーションに特に有効です。次に、例を示します。
Set OraDatabase = OraSession. OpenDatabase("Exampledb", "scott/tiger", 0&) 'Add the job input parameter with initial value MANAGER. OraDatabase.Parameters.Add "job", "MANAGER", 1 'Add the deptno input parameter with initial value 10. OraDatabase.Parameters.Add "deptno", 10, 1 'Add the job input parameter with initial value MANAGER. OraDatabase.Parameters.Add "EmpCur", 0, 1 OraDatabase.Parameters("Empcur").ServerType = ORATYPE_CURSOR 'Disable the job parameter for now. OraDatabase.Parameters("job").AutoBindDisable set OraSqlStmt = CreateSQL("Begin GetEmpData(:Empcur, :deptno) End;",0&)
PL/SQL文の処理中は、job
パラメータ・オブジェクトが参照されていないことに注意してください。
OO4Oは、OraParamArray
オブジェクトを介したOracleデータベースへの配列インタフェースをサポートしています。この配列インタフェースによって、大量のデータを1回のネットワーク・トリップで転送できます。これは、ExecuteSQL
またはCreateSQL
メソッドを介してPL/SQL文またはSQL文を処理するときに特に役立ちます。たとえば、配列処理なしでリモート・データベースに100行を挿入するためには、ExecuteSQL
またはCreateSQL
を100回コールする必要があり、100回のネットワーク・トリップが発生します。次に、例を示します。
For I = 1 to 100 OraParameter("EMPNO").Value = xxxx OraParameter("ENAME").Value = 'yyyy' OraParameter("DEPTNO").Value = zz OraDatabase.ExecuteSql("insert into emp values (:EMPNO,:ENAME,:DEPTNO)"); Next I
次の例では、配列を使用し、ネットワーク・トリップは1回のみ行います。
'ENAMEARR,:EMPNOARR,:DEPTNOARR are parameter arrays For I = 1 to 100 OraParameter("EMPNOARR").Put_Value xxxx, I OraParameter("ENAMEARR").Put_Value 'yyyy' ,I OraParameter("DEPTNOARR").Put_Value zz, I Next I 'Now call the ExecuteSQL only once OraDatabase.ExecuteSql("insert into emp values(:EMPNOARR," & _ ":ENAMEARR, :DEPTNOARR)");
アプリケーションでダイナセットを更新しない場合は、ORADYN_READONLY
(H4
)オプションを使用して読取り専用のダイナセットを作成できます。このオプションによって、SQL文をローカルで解析するためのオーバーヘッドとSQL文を実行するためのネットワーク・トリップ回数を削減し、パフォーマンスを向上させることができます。
アプリケーションでスクロール可能なダイナセットが不要な場合は、ORADYN_NOCACHE
(H8
)オプションを使用して前方参照専用のダイナセットを作成できます。このオプションによって、ローカル・キャッシュ・ファイルを作成するためのオーバーヘッドと、そのファイルからデータを読み書きするためのオーバーヘッドを削減し、パフォーマンスを向上させることができます。
このPL/SQL一括収集機能を使用すると、PL/SQLの無名ブロックを使用して、1回のネットワーク・トリップで大量のデータを選択できます。OO4OのOraDynaset
オブジェクトは、SQL文の実行中にデータの配列を選択します。このため、ネットワーク・ラウンドトリップ回数の増加、キャッシュ・ファイルや内部オブジェクトの追加作成などのオーバーヘッドが生じます。このオーバーヘッドが理由でダイナセットを使用しない場合、この機能はデータ配列の選択に役立ちます。選択されるデータは、OraParamArray
オブジェクトまたはOraCollection
オブジェクトのいずれかとしてバインドできます。
次の例では、OraCollection
インタフェースを使用したPL/SQL一括収集機能を示します。ここでは、1回のネットワーク・ラウンドトリップにより、少ないオーバーヘッドでenames
の配列が選択される方法を示します。
Set OraDatabase = OraSession.OpenDatabase("Exampledb", "scott/tiger", 0&)
'create a VARRAY type ENAMELIST in the database
OraDatabase.ExecuteSQL ("create type ENAMELIST as VARRAY(50) OF VARCHAR2(20)")
'create a parameter for ENAMELIST VARRAY
OraDatabase.Parameters.Add "ENAMES", Null, ORAPARM_OUTPUT, 247,"ENAMELIST"
'execute the statement to select all the enames from ename column of emp table
OraDatabase.ExecuteSQL ("BEGIN select ENAME bulk collect into" & _
":ENAMES from emp; END;")
'here OraParameter object returns EnameList OraCollection
Set EnameList = OraDatabase.Parameters("ENAMES").Value
'display all the selected enames
FOR I = 1 to EnameList.Size
msgbox Enamelist(I)
NEXT I
次の新しい型が、Oracle8iから導入されました(「ラージ・オブジェクト(LOB)の使用」を参照)。
BLOB
CLOB
BFILE
こららの型の仕様により、OO4Oは、LONG
またはLONG
RAW
型を使用するよりもはるかに迅速にそれらにアクセスできます。そのため、既存のLONG
RAW
コードをBLOB
、CLOB
およびBFILE
に変換し、新しいアプリケーションではLOBおよびBFILE
のみを使用するようにしてください。LOBおよびBFILE
型にアクセスするには、下位互換性のためにのみ提供されているLONG
RAW
の大量処理メソッドのかわりに、OraLOBオブジェクトを使用することをお薦めします。OraLOBでは最大限のコントロールが可能であることに注意してください。
LOBデータ型は、いくつかの点でLONG
やLONG
RAW
データ型と異なります。
1つの表に複数のLOB列を含めることはできますが、LONG
列は1つのみです。
1つ以上のLOB列を含んだ表はパーティション化できますが、LONG
列を含む表はパーティション化できません。
LOBの最大サイズが4GBであるのに対し、LONG
の最大サイズは2GBです。
LOBはデータへのランダム・アクセスをサポートしますが、LONG
データ型がサポートするのは順次アクセスのみです。
LOBデータ型(NCLOB
を除く)はユーザー定義オブジェクト型の属性にできますが、LONG
データ型はできません。
LOBのクライアント側でのバッファリングは、複数の少量書込みの最適化に使用されます。
LOBデータは、データベース表領域(BFILE
型)以外のオペレーティング・システム・ファイルに格納できます。
移行を容易にするために、次の各メソッドではBLOB
、CLOB
およびBFILE
型を使用できます。
LONG
RAW
の大量処理メソッドを使用している古いアプリケーションの場合は、移行の際に小規模なコード変更が必要です。主コードを変更するときは、使用する前に、NULLのBLOB
とCLOB
型を空白で更新する必要があります。
OO4Oのエラーは、次のカテゴリに分類されます。
OO4Oオートメーション・サーバーのプログラム・インタフェースは、OO4Oインプロセス・オートメーション・サーバーです。メソッドの実行中に発生するエラーは、多くの場合、OLEオートメーション・エラー(ERR = 440
、ERROR$="OLE自動化エラー:: :0"
)として報告されます。
エラーが発生した場合は、OraSession
およびOraDatabase
オブジェクトのLastServerErr
プロパティをチェックして、Oracleデータベース・エラーが発生しているかどうかを確認してください。LastServerErr
が0(ゼロ)以外の場合、エラーはOO4Oオートメーション・サーバーで発生しています。
OO4Oオートメーション・サーバーのエラーを確認するには、ERROR$
ファンクションが戻した文字列内の"OIP-NNNN"
(NNNN
は表5-1に示すエラー番号)を調べます。
注意: これらの値は、ORACLE_BASE\\ORACLE_HOME \oo4o ディレクトリのoraconst.txt ファイルにあります。 |
関連項目: |
表5-1に、Oracle OLEオートメーション・エラーを示します。
表5-1 Oracle OLEオートメーション・エラー
定数 | 値 | 説明 |
---|---|---|
|
|
内部エラー: アドバイザリ接続が無効です。 |
|
|
空のダイナセットからフィールド値を取り出そうとしました。 |
|
|
無効なフィールド名が指定されました。 |
|
|
無効なフィールド索引が指定されました。索引の範囲は |
|
|
すでに進行中のトランザクションに、 |
|
|
最初に |
|
|
最初に |
|
|
内部エラー: システムが、存在しないダイナセットを破棄しようとしました。 |
|
|
無効な行を参照しようとしました。このエラーは、 |
|
|
データ・キャッシュ用の一時ファイルを作成しようとして、エラーが発生しました。 |
|
|
|
|
|
内部エラー: システムが、存在しないセッションを破棄しようとしました。 |
|
|
存在しない(フィールド・コレクション以外の)コレクションの名前付きオブジェクトを参照しようとしました。 |
|
|
内部エラー: 接続名が重複しています。 |
|
|
内部エラー: システムが、存在しない接続を破棄しようとしました。 |
|
|
無効なフィールド索引が指定されました。索引の範囲は |
|
|
内部エラー: システムが行に移動しようとしましたが、この操作はダイナセットでサポートされていません。 |
|
|
更新不可のダイナセット・データを変更しようとしました。 |
|
|
最初に |
|
|
ローカル・キャッシュのデータを編集しようとしましたが、Oracle Databaseのデータが変更されていました。 |
|
|
データ・バインディング用バッファがメモリー不足です。 |
|
|
無効なブックマークが指定されました。 |
|
|
内部エラー: バインド変数が使用可能になっていません。 |
|
|
|
|
|
無効なオフセット・パラメータまたは無効な長さのパラメータが |
|
|
|
|
|
引数に無効な値が入力されました。 |
|
|
|
|
|
|
|
|
|
|
|
無効なキャッシュ・パラメータが指定されました。 |
|
|
|
|
|
内部エラー: メモリーが足りません。 |
|
|
|
|
|
|
|
|
|
|
|
配列を処理中にエラーが発生しました。詳細は、Windowsディレクトリの |
|
|
内部エラー: クリップボードをオープンまたはクローズできませんでした。 |
|
|
|
|
|
|
|
|
PL/SQLカーソルから作成したダイナセットに対し、SQLプロパティを設定しようとしました。 |
|
|
このセッションのデータベース・プールがすでに存在します。 |
|
|
未使用のデータベース・オブジェクトをプールから取得できません。 |
|
|
入力型がフィールドまたはパラメータの型と互換性がありません。 |
|
|
クローンのオブジェクトを編集しようとしました。 |
|
|
パラメータ配列の型、または拡張型の配列を変更しようとしました。 |
表5-2に、非ブロック化エラーを示します。
Find
メソッドの解析機能エラーは、解析機能がFind
メソッド内の式を評価できないときに発生します。このエラーは、エラーの原因となった式の部分を示します。
表5-3に、Find
メソッドの解析機能エラーを示します。
表5-3 Findメソッドの解析機能エラー
定数 | 値 | 説明 |
---|---|---|
|
|
スタックがオーバーフローしています。 |
|
|
構文エラーです。 |
|
|
カッコの位置が適切ではありません。 |
|
|
引用符の位置が適切ではありません。 |
|
|
警告: 右カッコが欠落しています。 |
|
|
左カッコが必要です。 |
|
|
不明な解析機能エラー状態です。 |
|
|
サポートされない構文です。 |
|
|
無効な列名です。 |
|
|
トークン・サイズが最大値を超えています。 |
|
|
サポートされないデータ型です。 |
|
|
予期しないトークンが見つかりました。 |
|
4508 |
予期しない句の終わりが見つかりました。 |
Find
メソッドのランタイム・エラーは、システムがfind式を評価できないときに発生します。このエラーは、ごくまれに発生します。発生した場合、解析機能は不正なコードを生成することもあります。
表5-4に、Find
メソッド・ランタイム・エラーを示します。
表5-4 Findメソッド・ランタイム・エラー
定数 | 値 | 説明 |
---|---|---|
|
|
内部エラー: 指示が無効です。 |
|
|
内部エラー: スタックのオーバーフローまたはアンダーフローです。 |
|
|
無効な型変換です。 |
|
|
無効なデータ型です。 |
|
|
SQLファンクションに引数がありません。 |
|
|
無効な比較です。 |
|
|
dualからの |
|
|
dualからの |
|
|
演算子の使用が無効です。 |
表5-5に、OraObject
インスタンス・エラーを示します。
表5-5 OraObjectインスタンス・エラー
定数 | 値 | 説明 |
---|---|---|
|
|
クライアント側のオブジェクト・キャッシュで |
|
|
SQL文への |
|
|
|
|
|
|
|
|
バインド操作に対する入力オブジェクト型が無効です。 |
|
|
フェッチした |
|
|
|
|
|
|
表5-6に、LOBエラーを示します。
表5-6 LOBエラー
定数 | 値 | 説明 |
---|---|---|
|
|
LOB読取り/書込み操作に指定したシーク値が無効です。 |
|
|
|
|
|
|
|
|
入力バッファが |
|
|
入力バッファが |
|
|
LOB書込み操作のバッファ長が無効です。 |
|
|
このモードでの |
|
|
バインド操作に対する入力LOBが無効です。 |
|
|
クローンLOBオブジェクトに対する |
|
|
指定したファイルをLOB操作でオープンできませんでした。 |
|
|
LOB操作でファイルの |
|
|
|
表5-7に、Oracle Streamsアドバンスト・キューイング・エラーを示します。
表5-7 Oracle Streamsアドバンスト・キューイング・エラー
定数 | 値 | 説明 |
---|---|---|
|
|
|
|
|
|
|
|
ペイロード・オブジェクトの作成でエラーが発生しました。 |
|
|
サブスクライバの最大数を超えています。 |
|
|
|
表5-8に、OraCollection
エラーを示します。
表5-8 OraCollectionエラー
定数 | 値 | 説明 |
---|---|---|
|
|
|
|
|
指定した索引に対する要素が存在していません。 |
|
|
無効なコレクションの索引が指定されました。 |
|
|
|
|
|
スカラー要素型でない型を含むコレクションから変数 |
表5-9に、OraNumber
エラーを示します。
最新のOracleエラー・テキストは、OraSession
またはOraDatabase
オブジェクトのLastServerErr
とLastServerErrText
プロパティから入手できます。
OraSession
オブジェクト
OraSession
オブジェクトのLastServerErr
とLastServerErrText
プロパティは、OpenDatabase
メソッドに関するエラーなど、接続に関連するすべてのエラーを戻します。
OraDatabaseオブジェクト
OraDatabase
オブジェクトのLastServerErr
とLastServerErrText
プロパティは、CreateDynaset
、CreateSQL
およびExecuteSQL
メソッドに関するエラーなど、Oracleカーソルに関連するすべてのエラーを戻します。
Oracle Data Controlエラーは、Oracleデータ・コントロール固有のエラーです。データ・コントロールに視覚的にアクセスしている間、OO4Oオートメーション・サーバー固有のエラーは、ODCERR_AUTOMATION
のエラー・コードとともにOLEオートメーション・サーバー・エラーとして報告されます。Oracle Data Control固有のエラー・コードは、Error()
イベントのDataErr
パラメータから取り出されます。
表5-10に、Oracle Data Controlエラーを示します。
表5-10 Oracle Data Controlエラー
定数 | 値 | 説明 |
---|---|---|
|
|
Oracleインプロセス・サーバーの初期化に失敗しました。レジストリを調べて、Oracleインプロセス・サーバーの正しい位置を調べる必要があります。 |
|
|
内部エラー。インプロセス・サーバー・インタフェースの問合せに失敗しました。 |
|
|
Oracleインプロセス・サーバーのエラーが発生しました。 |
|
|
初期化する前にOracle Data Controlにアクセスしようとしました。 |
|
|
バインド済コントロールが、無効なフィールド索引にアクセスしようとしました。 |
|
|
バインド済コントロールが、無効なフィールド名にアクセスしようとしました。 |
|
|
内部エラー。バインド済コントロールから、要求したバインディングにメモリーを割り当てようとして、エラーが発生しました。 |
|
|
Oracle Data Controlは、要求された種類のブックマークをサポートしていません。 |
|
|
Oracle Data Controlは、要求された型にフィールド値を変換できませんでした。 |
|
|
セッションのプロパティの設定は許可されていません。 |
|
|
データベースのプロパティの設定は許可されていません。 |
|
|
Oracle Data Controlは、PICTUREまたはRAWデータをバインド済コントロールから直接更新しません。 |
|
|
|
|
|
|
この項では、次の内容に関連する一般的なエラーについて説明します。
関連項目: エラーに関する詳細情報は、『Oracle Databaseエラー・メッセージ』を参照してください。 |
OLEの初期化エラーとオートメーション・エラーの最も多い原因は、ソフトウェアがインストールされていないこと、または正しくインストールされていないことです。指定したソフトウェアが正しくインストールされていることを確認してください。次に、メソッド名とプロパティ名が正しく指定されていること、Oracleオブジェクトがすべてオブジェクト型として宣言されていることを確認してください。
表5-11に、OLEエラーの原因と解決策を示します。
表5-11 OLEエラーの原因と解決策
考えられる原因 | 解決策 |
---|---|
使用しているシステムに、Microsoft OLEオートメーションまたはランタイム・ファイルが存在しないか、存在していても古いバージョンのファイルです。 |
次のような最新バージョンのファイルがインストールされていることを確認してください。
|
Oracle Objects for OLEのオブジェクト情報がWindowsの登録データベースに登録されていません。 |
Oracle Objects for OLEを再インストールするか、または |
使用しているシステムに、Oracle Required Support Filesがありません。
|
OO4Oのreadme.htmファイルをチェックし、必要なOracle Databaseクライアントのバージョンを確認してインストールしてください。 |
使用しているシステムに、Oracleネットワーク製品がないか、またはファイルの位置がPATHで設定されていません。 |
Oracleネットワーク製品をインストールするか、またはPATHに環境変数に追加して、ファイルが存在するディレクトリを示してください。 |
メソッド名またはプロパティ名のスペルが正しくありません。 |
『Oracle Objects for OLE開発者ガイド』(このガイド)を調べて、正しいスペルに修正してください。 |
間違ったオブジェクトからメソッドまたはプロパティを参照しました。 |
『Oracle Objects for OLE開発者ガイド』(このガイド)を調べて、正しいオブジェクトに修正してください。 |
使用しているシステムに、 |
Oracle Objects for OLEを再インストールするか、またはこれらのファイルが存在するディレクトリを 注意: |
Oracleネットワークのエラーで最も多い原因は、接続情報の指定が間違っていることです。Oracle Objects for OLEの接続情報の指定は、Open Database Connectivity(ODBC)を使用する場合とは異なります。Oracle Objects for OLEの使用前に、接続情報を正しく指定していることを検証し、次に、ネットワークの接続が正しく動作していることを確認してください。接続テストの情報と受け取る可能性のあるOracleネットワークのエラー情報は、該当するOracleネットワーク製品のドキュメントに記載されています。
表5-12に、Oracleネットワークのエラーを示します。
アクセス違反の最も頻度の高い原因は、OO4Oオートメーション・サーバー、Oracle Required Support FilesまたはOLEを必要とする他のアプリケーションの実行中に、Oracle Objects for OLEをインストールすることです。これを回避するには、Windowsの開始直後、他のアプリケーションの実行前に、Oracle Objects for OLEをインストールしてください。
表5-13に、アクセス違反を示します。
表5-13 アクセス違反
考えられる原因 | 解決策 |
---|---|
|
重複しているファイルを削除します。oip |
|
重複しているファイルを削除します。通常、Oracle Required Support FilesのDLLは
|
|
重複しているファイルを削除します。OLEのDLL(「OO4Oファイルの場所」の項にリストされています)は、必ず |