8 CursorクラスおよびCursorの概念
この章では、Oracle OLAP Java APIのCursorクラスおよび問合せの結果を取得するために使用する関連クラスについて説明します。 また、Cursorの位置、フェッチ・サイズおよびエクステントの概念についても説明します。 Cursorとその関連オブジェクトの作成と使用の例については、「問合せ結果の取得」を参照してください。
この章の内容は次のとおりです。
OLAP Java API Cursorオブジェクトの概要
Cursorは、Sourceで指定された結果セットを取得します。 Cursorは、CursorManagerのcreateCursorメソッドをコールして作成します。 CursorManagerは、DataProviderのcreateCursorManagerメソッドをコールして作成します。
Oracle OLAP SQL GeneratorによってSourceに対して生成されたSQLを取得するには、Cursorを作成する必要はありません。 SourceのSQLを取得するには、DataProviderのcreateSQLCursorManagerメソッドを使用して、SQLCursorManagerを作成します。 次に、OLAP Java API外部のクラス、またはその他のメソッドを使用して、生成されたSQLを使用してデータを取得します。
Cursorの作成
DataProviderのcreateCursorManagerメソッドのいずれか1つをコールして、そのメソッドにSourceを渡すことによって、CursorManagerを作成します。Cursorの動作を変更する場合、CursorInfoSpecificationを作成し、そのメソッドを使用して動作を指定します。 このCursorInfoSpecificationおよびSourceを引数とするメソッドを使用して、CursorManagerを作成します。CursorManagerのcreateCursorメソッドをコールして、Cursorを作成します。
Cursorを作成できないSource
一部のSourceオブジェクトは、Cursorがデータ・ストアから取得できるデータを指定しません。 値を持つCursorを作成できないSourceオブジェクトは次のとおりです。
-
計算不可能な操作を指定する
Source。 たとえば、無限再帰を指定するSourceです。 -
無限結果セットを定義する
Source。 たとえば、すべてのStringオブジェクトのセットを表す基本Sourceです。 -
要素を持たないか、要素を持たない別の
Sourceを含むSource。 例は、DataProviderのgetEmptySourceメソッドによって返されたSourceと、空のSourceから派生した別のSourceです。 もう1つの例は、MdmDimensionから取得したプライマリSourceの値を選択し、選択した値がディメンションに存在しないことに起因する、派生したSourceです。
このようなSourceのCursorを作成してCursorの値を取得しようとすると、Exceptionが発生します。
CursorオブジェクトおよびTransactionオブジェクト
派生したSourceを作成するか、Templateの状態を変更するときは、現在のTransactionのコンテキストでSourceを作成します。 Sourceは、作成するTransactionまたはそのTransactionの子Transactionでアクティブです。 あなたのためにCursorを作成できるように、現在のTransactionでSourceがアクティブでなければなりません。
導出Sourceの作成は、書込みTransactionで実行されます。 Cursorの作成は、読取りTransactionで実行されます。 派生したSourceを作成し、そのSourceのCursorを作成する前に、アプリケーションが使用しているTransactionProviderのcommitCurrentTransactionメソッドを呼び出すことによって、Transactionを読み取りTransactionに変更する必要があります。 TransactionおよびTransactionProviderオブジェクトの詳細については、「TransactionProviderの使用」を参照してください。
パラメータ化されたSourceを含む問合せ用に作成するCursorについては、Parameterオブジェクトの値を変更して、Transactionを再度コミットすることなく、Cursorの新しい値を取得することができます。 パラメータ化されたSourceオブジェクトの詳細については、「ソース・オブジェクトの理解」を参照してください。
Cursorクラス
oracle.olapi.data.cursorパッケージでは、次の表に示すインタフェースがOracle OLAP Java APIによって定義されます。
| インタフェース | 説明 |
|---|---|
|
|
現在の位置の概念をカプセル化する抽象スーパークラス。 |
|
|
現在の位置に1つの値を持つ |
|
|
子 |
Cursorの構造
Cursorの構造には、自身に関連付けられたSourceの構造が反映されます。 Sourceに出力がない場合、そのSourceのCursorはValueCursorです。 Sourceに1つ以上の出力がある場合、そのSourceのCursorはCompoundCursorです。 CompoundCursorは、子としてCompoundCursorのSourceのベースと1つ以上の出力Cursorオブジェクトの値を持つベースValueCursorを持ちます。
Sourceの出力は別のSourceです。 出力Source自体も出力を持つことができます。 Sourceの出力の子Cursorは、出力Sourceに出力がない場合はValueCursorであり、出力がある場合はCompoundCursorです。
「例8-1」は、選択した月間に選択した製品アイテムの価格を指定する問合せを作成します。 この例では、timeHierは時間値のディメンションの階層のSourceであり、prodHierは製品値のディメンションの階層のSourceです。
prodSelまたはtimeSel用のCursorを作成すると、prodSelとtimeSelの両方に出力がないため、CursorはValueCursorです。
unitPriceオブジェクトは、製品単位の価格の値を表すMdmBaseMeasureのSourceです。 MdmBaseMeasureは、入力として製品と時間を表すMdmPrimaryDimensionオブジェクトを持ち、unitPrice Sourceは、それらのディメンションのSourceオブジェクトを入力として持っています。
この例では、ディメンション階層の要素を選択してから、選択のSourceオブジェクトをメジャーのSourceに結合して、querySourceを生成します。これは、出力としてprodSelおよびtimeSelを持ちます。
例8-1 querySource問合せの作成
Source timeSel = timeHier.selectValues(new String[]
{"CALENDAR_YEAR::MONTH::2001.01",
"CALENDAR_YEAR::MONTH::2001.04",
"CALENDAR_YEAR::MONTH::2001.07",
"CALENDAR_YEAR::MONTH::2001.10"});
Source prodSel = prodHier.selectValues(new String[]
{"PRODUCT_PRIMARY::ITEM::ENVY ABM",
"PRODUCT_PRIMARY::ITEM::ENVY EXE",
"PRODUCT_PRIMARY::ITEM::ENVY STD"});
Source querySource = unitPrice.join(timeSel).join(prodSel);
querySourceで定義された結果セットは、選択した月の選択した製品の単価値です。 結果は出力によって整理されます。 timeSelはunitPrice.join(prodSel)操作によって生成されたSourceに結合されているため、timeSelはより遅く変化する出力です。つまり、結果セットは選択された各時間値に対して選択された製品のセットを指定します。 各時間値について、結果セットは3つの製品値を有するので、製品値は時間値よりも速く変化します。 querySourceのベースValueCursorの値は、毎日の各製品に1つの価格価値があるため、すべての中で最も変化が速いです。
「問合せ結果の取得」の「例9-1」は、querySourceのCursor、queryCursorを作成します。 querySourceには出力があるので、queryCursorはCompoundCursorです。 queryCursorのベースValueCursorには、querySourceを作成した操作のベースSourceであるunitPriceの値があります。 unitPriceの値は、出力によって指定された値です。 queryCursorの出力は、prodSelの値を持つValueCursorと、timeSelの値を持つValueCursorです。
図8-1 CompoundCursorであるqueryCursorの構造
この図は、queryCursorの構造を示しています。 ベースValueCursorと2つの出力ValueCursorオブジェクトは、親CompoundCursorであるqueryCursorの子です。

図8-1 CompoundCursorであるqueryCursorの構造の説明
次に、queryCursorの値を表形式で示します。 左の列は時間値、中央の列は製品値、右の列は月の製品の単位価格を表しています。
| 月 | 製品 | 単位価格 |
|---|---|---|
|
2001.01 |
ENVY ABM |
3042.22 |
|
2001.01 |
ENVY EXE |
3223.28 |
|
2001.01 |
ENVY STD |
3042.22 |
|
2001.04 |
ENVY ABM |
2412.42 |
|
2001.04 |
ENVY EXE |
3107.65 |
|
2001.04 |
ENVY STD |
3026.12 |
|
2001.07 |
ENVY ABM |
2505.57 |
|
2001.07 |
ENVY EXE |
3155.91 |
|
2001.07 |
ENVY STD |
2892.18 |
|
2001.10 |
ENVY ABM |
2337.30 |
|
2001.10 |
ENVY EXE |
3105.53 |
|
2001.10 |
ENVY STD |
2856.86 |
ValueCursorから値を取得する例については、「問合せ結果の取得」を参照してください。
Cursorの動作の指定
CursorSpecificationオブジェクトは、対応するCursorオブジェクトの動作の一部の側面を指定します。 対応するCursorオブジェクトを作成する前に、その動作をCursorSpecificationに指定する必要があります。 動作を指定するには、次のCursorSpecificationメソッドを使用します。
-
setDefaultFetchSize -
setExtentCalculationSpecified -
setParentEndCalculationSpecified -
setParentStartCalculationSpecified -
specifyDefaultFetchSizeOnChildren(CompoundCursorSpecificationの場合のみ)
CursorSpecificationには、動作が指定されているかどうかを確認するためのメソッドも含まれています。 それらのメソッドを次に示します。
-
isExtentCalculationSpecified -
isParentEndCalculationSpecified -
isParentStartCalculationSpecified
CursorSpecificationメソッドを使用して、デフォルトのフェッチ・サイズの設定、エクステントの計算、あるいは親の中での値の開始位置または終了位置の計算を実行した場合、次のCursorメソッドを正常に実行できます。
-
getExtent -
getFetchSize -
getParentEnd -
getParentStart -
setFetchSize
Cursorビヘイビアの指定の例については、「問合せ結果の取得」を参照してください。 フェッチ・サイズの詳細については、「"フェッチ・サイズについて"」を参照してください。 Cursorの範囲については、「"カーソルのエクステントとは何ですか?"」を参照してください。 Cursorの現在の値の親Cursorの開始位置と終了位置については、「"カーソル内の親の開始および終了位置について"」を参照してください。
CursorInfoSpecificationクラス
CursorInfoSpecificationインタフェースとそのサブインタフェースのCompoundCursorInfoSpecificationおよびValueCursorInfoSpecificationは、抽象クラスCursorSpecificationと具象クラスCompoundCursorSpecificationおよびValueCursorSpecificationのメソッドを指定します。 CursorSpecificationでは、対応するCursorの動作の特定の側面を指定できます。 CursorInfoSpecificationインタフェースを直接的または間接的に実装するクラスのインスタンスを作成できます。
SourceのCursorSpecificationを作成するには、DataProviderのcreateCursorInfoSpecificationメソッドをコールします。 このメソッドは、CompoundCursorSpecificationまたはValueCursorSpecificationを戻します。 CursorSpecificationのメソッドを使用すると、Cursorの動作の側面を指定できます。 また、CursorSpecificationを、cursorInfoSpec引数としてDataProviderのcreateCursorManagerメソッドに渡すことにより、CursorManagerを作成できます。
CursorSpecificationメソッドを使用すると、次の操作を実行できます。
-
CursorSpecificationに対応するSourceを取得できます。 -
対応する
Cursorのデフォルトのフェッチ・サイズを取得または設定できます。 -
Oracle OLAPで
Cursorのエクステントを計算するように指定できます。 -
エクステントの計算が指定されているかどうかを判断できます。
-
Oracle OLAPが、親
Cursor内の対応するCursorの現在の値の開始位置または終了位置を計算するように指定します。 親の中での値の開始位置および終了位置がわかっている場合、親Cursorがその値に対して持っている、速く変化する要素の数を判断できます。 -
対応する
Cursorの、親の中での現在の値の開始位置または終了位置の計算が指定されているかどうかを判断できます。 -
CursorSpecificationVisitorを受け入れることができます。
詳細は、「"カーソルの位置と範囲について"」および「"フェッチ・サイズについて"」を参照してください。
oracle.olapi.data.sourceパッケージでは、次の表に示すクラスがOracle OLAP Java APIによって定義されます。
| インタフェース | 説明 |
|---|---|
|
|
|
|
|
|
|
|
1つ以上の出力を持つ |
|
|
|
|
|
値を持ち、出力を持たない |
|
|
|
Cursorの構造は、そのCursorSpecificationの構造と同じです。 各ValueCursorSpecificationまたはCompoundCursorSpecificationは、対応するValueCursorまたはCompoundCursorを持ちます。 Cursorから特定の情報や動作を取得できるようにするには、アプリケーションは、Cursorを作成する前に、対応するCursorSpecificationのメソッドを呼び出すことによって、情報または動作が必要であることを指定する必要があります。
CursorManagerクラス
CursorManagerを使用すると、SourceのCursorを作成できます。 作成されたCursorオブジェクトのデータのバッファリングは、DataProviderのいずれかのcreateCursorManagerメソッドによって戻されるクラスによって管理されます。
同じCursorManagerから複数のCursorを作成することができます。これは、結果セットのデータを表やグラフなどの異なるフォーマットで表示するのに便利です。 CursorManagerによって作成されたすべてのCursorオブジェクトは、デフォルトのフェッチ・サイズなどの仕様が同じです。 Cursorオブジェクトは同じ仕様を持つため、CursorManagerで管理されるデータを共有できます。
SQLCursorManagerには、Source用のOracle OLAP SQL Generatorによって生成されたSQLを戻すメソッドがあります。 1つ以上のSQLCursorManagerオブジェクトを作成するには、DataProviderのcreateSQLCursorManagerまたはcreateSQLCursorManagersメソッドをコールします。 Cursorの作成にSQLCursorManagerは使用しません。 代わりに、OLAP Java APIの外部のクラスでSQLCursorManagerによって戻されたSQLを使用するなどの方法で、問合せで指定されたデータを取得します。
CursorManagerのCursorInfoSpecificationの更新
アプリケーションがOLAP Java API Templateオブジェクトを使用していて、Templateによって生成されたSourceの構造を変更するようにTemplateの状態が変化すると、SourceのCursorInfoSpecificationオブジェクトは無効になります。 変更されたSourceに対して新しいCursorInfoSpecificationオブジェクトを作成する必要があります。
新しいCursorInfoSpecificationを作成した後、そのSourceの新しいCursorManagerを作成できます。 ただし、新しいCursorManagerは、必ずしも作成する必要はありません。 既存のCursorManagerのupdateSpecificationメソッドを呼び出して、前のCursorInfoSpecificationを新しいCursorInfoSpecificationに置き換えることができます。 その後、CursorManagerから新しいCursorを作成できます。
Cursorの位置およびエクステント
Cursorには、1つ以上の位置があります。 Cursorの「現在位置」は、現在Cursorでアクティブな位置です。 Cursorの現在の位置を移動するには、CursorのsetPositionまたはnextメソッドを呼び出します。
Oracle OLAPは、getCurrentValueメソッドの呼び出しなど、Cursorの操作を試行するまで、Cursorで設定した位置を検証しません。 現在の位置を負の値またはCursorの位置の数より大きい値に設定してからCursor操作を試行すると、CursorはPositionOutOfBoundsExceptionをスローします。
Cursorの範囲は、「"カーソルのエクステントとは何ですか?"」で説明されています。
ValueCursorの位置
ValueCursorの現在の位置には、取得可能な1つの値が指定されています。 たとえば、prodSel (「"カーソルの構造"」で説明されている派生Source)は、製品のディメンションとその階層グループを指定するプライマリSourceの3つの製品の選択です。 prodSelのValueCursorには、3つの要素が存在します。 次の例では、ValueCursorの各要素の位置を取得し、その位置の値を表示します。
// prodSelValCursor is the ValueCursor for prodSel
println("ValueCursor Position Value ");
println("-------------------- ------------------------");
do
{
println(" " + prodSelValCursor.getPosition() +
" " + prodSelValCursor.getCurrentValue());
} while(prodSelValCursor.next());
前述の例によって表示される値は、次のとおりです。
ValueCursor Position Value
-------------------- -------------------------------
1 PRODUCT_PRIMARY::ITEM::ENVY ABM
2 PRODUCT_PRIMARY::ITEM::ENVY EXE
3 PRODUCT_PRIMARY::ITEM::ENVY STD
次の例では、prodSelValCursorの現在の位置を2に設定し、その位置の値を取得します。
prodSelValCursor.setPosition(2); println(prodSelValCursor.getCurrentString());
前述の例によって表示される値は、次のとおりです。
PRODUCT_PRIMARY::ITEM::ENVY EXE
ValueCursorの現在の値を取得する他の例については、「問合せ結果の取得」を参照してください。
CompoundCursorの位置
CompoundCursorには、その子孫ValueCursorオブジェクトの要素セットごとに1つの位置が存在します。 CompoundCursorの現在の位置によって、それらのセットのいずれかが指定されます。
たとえば、querySource(例8-1で作成したSource)には、メジャーunitPriceからの値が含まれます。 これらの値は、異なる時点での製品の単位価格です。 querySourceの出力は、時間ディメンションから選択された4つの月の値および製品ディメンションから選択された3つの製品の値を表すSourceオブジェクトです。
querySourceの結果セットは、各タプル(出力値の各セット)に1つのメジャー値を持つため、値の合計数は12になります(4つの各月の3つの各製品に対して1つの値)。 したがって、querySource用に作成されたCompoundCursorであるqueryCursorには12の位置が存在します。
queryCursorの各位置によって、出力およびベースValueCursorの1つの位置セットが指定されます。 たとえば、queryCursorの位置1によって、その出力およびベースValueCursorの次の位置セットが決まります。
-
出力1の位置1(
timeSelのValueCursor) -
出力2の位置1(
prodSelのValueCursor) -
queryCursorのベースValueCursorの位置1(この位置には、出力の値によって指定されるunitPriceメジャーの値が存在します。)
図8-2 queryCursor内のCursorの位置
この例は、queryCursor CompoundCursor、ベースValueCursor、および出力の位置を示しています。

図8-2 queryCursor内のCursorの位置の説明
任意の1セットの出力値によってunitPriceの値が1つのみ指定されるため、queryCursorのValueCursorには位置が1つのみ存在します。 querySourceのような問合せの場合、そのCursorのValueCursorの値と位置は、ルート・レベルのCompoundCursorの任意の1つの位置に対して、一度にそれぞれ1つのみになります。
図8-3 queryCursorのクロス集計の表示
この図は、queryCursorからのデータの1つの可能な表示を示しています。 これは、4つの列および5つの行で構成されたクロス集計ビューです。 左の列は日付値です。 一番上の行は製品値です。 クロス集計の交差している各セルは、その月の製品の価格です。

図8-3 queryCursorのクロス集計の表示の説明
CompoundCursorでは、ValueCursorオブジェクトの位置が互いに相対的に調整されます。 CompoundCursorの現在の位置によって、その子孫ValueCursorオブジェクトの現在の位置が指定されます。
例8-2 CompoundCursorの位置の設定および現在の値の取得
この例では、queryCursorの位置を設定し、現在の値と子Cursorオブジェクトの位置を取得します。
CompoundCursor rootCursor = (CompoundCursor) queryCursor;
ValueCursor baseValueCursor = rootCursor.getValueCursor();
List outputs = rootCursor.getOutputs();
ValueCursor output1 = (ValueCursor) outputs.get(0);
ValueCursor output2 = (ValueCursor) outputs.get(1);
int pos = 5;
rootCursor.setPosition(pos);
println("CompoundCursor position set to " + pos + ".");
println("The current position of the CompoundCursor is = " +
rootCursor.getPosition() + ".");
println("Output 1 position = " + output1.getPosition() +
", value = " + output1.getCurrentValue());
println("Output 2 position = " + output2.getPosition() +
", value = " + output2.getCurrentValue());
println("VC position = " + baseValueCursor.getPosition() +
", value = " + baseValueCursor.getCurrentValue());
この例では、次の内容が表示されます:
CompoundCursor position set to 5. The current position of the CompoundCursor is 5. Output 1 position = 2, value = CALENDAR_YEAR::MONTH::2001.04 Output 2 position = 2, value = PRODUCT_PRIMARY::ITEM::ENVY EXE VC position = 1, value = 3107.65
queryCursorの位置は、querySourceの結果セットに常に各時間値に対する3つの製品値が含まれるという点で対称的です。 したがって、prodSelのValueCursorには、常にtimeSel ValueCursorの各値に対して3つの位置があります。 timeSelの出力ValueCursorは、prodSel ValueCursorよりも変化が緩やかです。
ただし、非対称の場合、ValueCursor内の位置の数は、遅く変化する出力に対して常に同じではありません。 たとえば、月2001.10の製品ENVY ABMの単位価格がNULLで(その日にその製品が販売されなかったため)、問合せでNULL値が抑制されている場合、queryCursorに含まれる位置は11のみです。 prodSelのValueCursorは、timeSelのValueCursorの位置が4の場合に2つの位置しか持たない。
「例8-3」は、メジャー値の比較に基づいて1つのディメンションの要素を選択することによって生成される非対称の結果セットを示します。 この例では、「例8-1」と同じ製品と時間の選択が使用されています。 製品、時間、販売チャネル、および顧客次元によってディメンション化された、販売された製品単位(units)の指標としてSourceを使用します。 chanSelおよびcustSelオブジェクトは、ディメンションの単一の値の選択です。 この例では、Source、querySource2が生成され、選択した製品のうち、選択した時間、チャネル、および顧客の値に対して複数のユニットを販売した製品を指定します。 querySource2は派生したSourceなので、この例は現在のTransactionをコミットします。
この例では、querySource2のCursorを作成し、CompoundCursorの位置をループし、CompoundCursorの最初の出力ValueCursorとValueCursorの位置と現在の値を取得し、ValueCursorオブジェクトの位置と値を表示します。 getLocalValueメソッドは、一意値からローカル値を抽出する、プログラム内のメソッドです。
例8-3 非対称問合せでの位置
// Create the query
prodSel.join(chanSel).join(custSel).join(timeSel).select(units.gt(1));
// Commit the current Transaction.
try
{ // The DataProvider is dp.
(dp.getTransactionProvider()).commitCurrentTransaction();
}
catch(Exception e)
{
output.println("Cannot commit current Transaction " + e);
}
// Create the CursorManager and the Cursor.
CursorManager cursorManager = dp.createCursorManager(querySource2);
Cursor queryCursor2 = cursorManager.createCursor();
CompoundCursor rootCursor = (CompoundCursor) queryCursor2;
ValueCursor baseValueCursor = rootCursor.getValueCursor();
List outputs = rootCursor.getOutputs();
ValueCursor output1 = (ValueCursor) outputs.get(0);
// Get the positions and values and display them.
println("CompoundCursor Output ValueCursor ValueCursor");
println(" position position | value position | value");
do
{
println(sp6 + rootCursor.getPosition() + // sp6 is 6 spaces
sp13 + output1.getPosition() + // sp13 is 13 spaces
sp7 + getLocalValue(output1.getCurrentString()) + //sp7 is 7 spaces
sp7 + baseValueCursor.getPosition() +
sp7 + getLocalValue(baseValueCursor.getCurrentString()));
}
while(queryCursor2.next());
この例によって、次のように表示されます。
CompoundCursor Output ValueCursor ValueCursor
position position | value position | value
1 1 2001.01 1 ENVY ABM
2 1 2001.01 2 ENVY EXE
3 1 2001.01 3 ENVY STD
4 2 2001.04 1 ENVY ABM
5 3 2001.07 1 ENVY ABM
6 3 2001.07 2 ENVY EXE
7 4 2001.10 1 ENVY EXE
8 4 2001.10 2 ENVY STD
prodSelから派生した値に対するValueCursorの要素の数は、出力ValueCursorの各値について同じではありません。 時間値2001.01の場合、3つの製品の販売数はすべて1を超えていますが、時間値2001.04の場合、販売数が1を超えている製品は1つのみです。 残りの2つの時間値2001.07と2001.10の場合、基準を満たす製品は2つです。 したがって、CompoundCursorのValueCursorには、時間値2001.01の場合は位置が3つ、時間値2001.04の場合は位置が1つのみ、時間値2001.07と2001.10の場合は位置が2つあります。
Cursor内での親の開始/終了位置
CompoundCursorから取得するデータの表示を効率的に管理するために、現在の遅く変化する値に対して存在する速く変化する値の数を把握することが必要な場合があります。 たとえば、クロス集計で、キューブの1つのエッジの値を1つの行に表示する場合、その行に対して表示する列の数を把握する必要がある場合があります。
子Cursorの現在の値に対していくつのより高速な可変値が存在するかを調べるには、親のCursorにその現在の値の開始位置と終了位置があります。 次に示すとおり、終了位置から開始位置を引き、1を足します。
long span = (cursor.getParentEnd() - cursor.getParentStart()) + 1;
結果は、親Cursor内の子Cursorの現在の値のspanです。これは、現在の値に対して最も速く変化する子Cursorの値がいくつあるかを示します。 開始位置と終了位置の計算には時間と計算リソースが多くかかるため、アプリケーションで情報が必要なときに計算を実行するように指定するだけです。
Oracle OLAP Java APIのCursorを使用すると、アプリケーションで、現在表示しているデータのみをクライアント・コンピュータに実際に存在させることができます。 Cursorのデータ量の指定については、「"フェッチ・サイズについて"」を参照してください。
ただし、クライアント・コンピュータのデータからは、Cursorの現在の値が開始または終了する親Cursorの位置を特定することはできません。 その情報を取得するには、CursorのgetParentStartおよびgetParentEndメソッドを使用します。
親Cursor内の子Cursorの値の開始および終了位置をOracle OLAPで計算するように指定するには、Cursorに対応するCursorSpecificationのsetParentStartCalculationSpecifiedおよびsetParentEndCalculationSpecifiedメソッドを呼び出します。 開始位置と終了位置の計算が指定されているかどうかは、そのCursorSpecificationのisParentStartCalculationSpecifiedまたはisParentEndCalculationSpecifiedメソッドをコールすることによって判断できます。 これらの計算を指定する例については、「問合せ結果の取得」を参照してください。
Cursorのエクステントの概要
Cursorのエクステントは、遅く変化する出力に対してそのCursorが含む要素の合計数です。
エクステントとは、たとえば正しい数の列または正しいサイズのスクロール・バーを表示するために使用できる情報です。 しかし、その程度は計算するのに費用がかかることがあります。 たとえば、キューブを表すSourceには4つの出力があります。 各出力には何百もの値があります。 出力セットのメジャーのすべてのNULL値とゼロ値が結果セットから削除された場合、SourceのCompoundCursorの範囲を計算するために、Oracle OLAPはCompoundCursorを作成する前に結果スペース全体を走査する必要があります。 エクステントを計算することを指定していない場合、Oracle OLAPはCursorのフェッチ・サイズで指定されたキューブの出力で定義された要素のセットをトラバースするだけで、必要に応じてアプリケーションでトラバースする必要があります。
Oracle OLAPでCursorのエクステントを計算するように指定するには、Cursorに対応するCursorSpecificationのsetExtentCalculationSpecifiedメソッドをコールします。 エクステントの計算が指定されているかどうかは、CursorSpecificationのisExtentCalculationSpecifiedメソッドをコールすることによって判断できます。 Cursorの範囲の計算を指定する例については、「問合せ結果の取得」を参照してください。
フェッチ・サイズ
OLAP Java APIのCursorは、Sourceの結果セット全体を表します。 ただし、Cursorはvirtual Cursorです。これは、Oracle OLAPから一度に結果セットの一部のみを取得するためです。 CursorManagerは、仮想Cursorを管理し、アプリケーションの必要に応じてOracle OLAPから結果を取得します。 CursorManagerで仮想Cursorが管理されることによって、アプリケーションの負荷が大幅に軽減されます。
1回のフェッチ操作でCursorが取り出すデータ量は、Cursorに指定された「サイズを取得」によって決まります。 フェッチ・サイズを指定すると、アプリケーションがローカル・コンピュータにキャッシュする必要があるデータの量を制限し、データの表示方法の要件を満たすようにキャッシュをカスタマイズすることによってフェッチの効率を最大限に向上させることができます。
問合せの作成時にParameterおよびパラメータ化Sourceオブジェクトを使用すると、Oracle OLAPによって戻される要素の数を調整することもできます。 Parameterオブジェクトの詳細については、「ソース・オブジェクトの理解」を参照してください。 パラメータ化されたSourceオブジェクトの使用例については、「ソース・メソッドを使用した問合せの作成」を参照してください。
SourceのCursorManagerを作成すると、Oracle OLAPによって、ルートのCursorSpecificationにデフォルトのフェッチ・サイズが指定されます。 デフォルトのフェッチ・サイズは、ルート・レベルのCursorSpecificationのsetDefaultFetchSizeメソッドを使用して変更できます。
同じCursorManagerから2つ以上のCursorオブジェクトを作成し、両方のCursorオブジェクトを同時に使用することができます。 これらのCursorオブジェクトは、個別のデータ・キャッシュを持つのではなく、CursorManagerによって管理されるデータを共有できます。
次の例は、問合せの結果を表とグラフの両方で表示するアプリケーションです。 アプリケーションで、SourceのCursorManagerを作成します。 このアプリケーションは、同じCursorManagerから、表ビューとグラフ・ビュー用に、2つの別個のCursorオブジェクトを作成します。 これらの2つのビューは、同じ問合せを共有し、同じデータを表示しますが、その表示形式は異なります。
図8-4 1つのSourceとその値を異なるビューで表示する2つのCursor
この図は、Sourceオブジェクト、Cursorオブジェクト、およびビューの関係を示しています。

図8-4 1つのSourceとその値を異なるビューで表示する2つのCursorの説明