この章では、問合せの結果を取得するために使用する、Oracle OLAP Java APIのCursorクラスおよびその関連クラスについて説明します。また、Cursorの位置、フェッチ・サイズおよびエクステントの概念についても説明します。Cursorおよびその関連オブジェクトの作成と使用の例については、第9章「問合せ結果の取得」を参照してください。
この章では、次の項目について説明します。
Cursorを使用すると、Sourceによって定義される結果セットを取得できます。Cursorは、CursorManagerのcreateCursorメソッドをコールして作成します。CursorManagerは、DataProviderのcreateCursorManagerメソッドをコールして作成します。
Oracle OLAP SQL GeneratorによってSourceに対して生成されたSQLを取得するには、Cursorを作成する必要はありません。SourceのSQLを取得するには、DataProviderのcreateSQLCursorManagerメソッドを使用して、SQLCursorManagerを作成します。次に、OLAP Java API外部のクラス、またはその他のメソッドを使用して、生成されたSQLを使用してデータを取得します。
SourceのCursorは次の手順で作成します。
DataProviderのcreateCursorManagerメソッドのいずれか1つをコールして、そのメソッドにSourceを渡すことによって、CursorManagerを作成します。Cursorの動作を変更する場合、CursorInfoSpecificationを作成し、そのメソッドを使用して動作を指定します。このCursorInfoSpecificationおよびSourceを引数とするメソッドを使用して、CursorManagerを作成します。
CursorManagerのcreateCursorメソッドをコールして、Cursorを作成します。
一部のSourceオブジェクトは、Cursorがデータ・ストアから取得できるデータを指定しません。値を持つCursorを作成できないSourceオブジェクトは次のとおりです。
計算不可能な操作を指定するSource。たとえば、無限再帰を指定するSourceです。
無限結果セットを定義するSource。たとえば、すべてのStringオブジェクトのセットを表す基本Sourceです。
要素を持たないSource、または要素を持たない他のSourceを含むSource。たとえば、DataProviderのgetEmptySourceメソッドによって戻されたSourceや、空のSourceから導出された別のSourceです。MdmDimensionから取得したプライマリSourceから値を選択することによって作成された導出Sourceで、選択された値がディメンションに存在しないSourceも該当します。
このようなSourceにCursorを作成してそのCursorの値を取得しようとすると、Exceptionが発生します。
導出Sourceを作成する、またはTemplateの状態を変更する場合、Sourceは、現行のTransactionのコンテキスト内で作成します。Sourceは、それを作成したTransactionの中またはそのTransactionの子Transactionの中でアクティブです。SourceのCursorを作成するには、そのSourceが現行のTransactionでアクティブである必要があります。
導出Sourceの作成は、書込みTransactionで実行されます。Cursorの作成は、読取りTransactionで実行されます。導出Sourceの作成後かつそのSourceのCursorの作成前に、アプリケーションで使用中のTransactionProviderのcommitCurrentTransactionメソッドをコールして、書込みTransactionを読取りTransactionに変更する必要があります。TransactionオブジェクトおよびTransactionProviderオブジェクトの詳細は、第7章「TransactionProviderの使用方法」を参照してください。
パラメータ化Sourceを含む問合せ用に作成するCursorの場合、Transactionを再度コミットしなくても、Parameterオブジェクトの値を変更して、Cursorの新しい値を取得できます。パラメータ化Sourceオブジェクトの詳細は、第5章「Sourceオブジェクトの理解」を参照してください。
oracle.olapi.data.cursorパッケージでは、次の表に示すインタフェースがOracle OLAP Java APIによって定義されます。
| インタフェース | 説明 |
|---|---|
Cursor |
現在の位置の概念をカプセル化する抽象スーパークラス。 |
ValueCursor |
現在の位置に1つの値を持つCursor。ValueCursorには、子Cursorオブジェクトは存在しません。 |
CompoundCursor |
子Cursorオブジェクトを持つCursor。含まれるCursorオブジェクトは、関連するSourceの値に対する子ValueCursorと、そのSourceの各出力用の出力子Cursorです。 |
Cursorの構造には、自身に関連付けられたSourceの構造が反映されます。Sourceが出力を持たない場合、そのSourceのCursorはValueCursorです。Sourceが1つ以上の出力を持つ場合、そのSourceのCursorはCompoundCursorです。CompoundCursorには、子として、そのCompoundCursorのSourceのベースの値を持つベースValueCursor、および1つ以上の出力Cursorオブジェクトが存在します。
Sourceの出力は、別のSourceです。出力Source自体も出力を持つことができます。Sourceの出力用の子Cursorは、出力Sourceが出力を持たない場合はValueCursor、出力を持つ場合はCompoundCursorです。
例8-1では、選択された月の選択された製品項目の価格を指定する問合せを作成します。この例では、timeHierは、時間値のディメンションの階層のSourceです。prodHierは、製品値のディメンションの階層のSourceです。
prodSelまたはtimeSelのCursorを作成する場合、いずれのCursorもValueCursorになります。これは、prodSelとtimeSelのどちらも出力を持たないためです。
unitPriceオブジェクトは、製品の単位価格の値を表すMdmMeasureのSourceです。MdmMeasureは、製品および時間を表す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で定義される結果セットは、選択された月の選択された製品の単位価格値です。結果は、出力によって編成されます。unitPrice.join(prodSel)操作によって生成されたSourceにtimeSelが結合されているため、timeSelは遅く変化する出力です。これは、結果セットによって、選択された各時間値に対して選択された一連の製品が指定されることを意味します。各時間値に対して、結果セットは3つの製品値を持つため、製品値は時間値より速く変化します。querySourceのベースValueCursorの値は、各日付の各製品に対して1つの値があるため、すべての値のうちで最も速く変化します。
第9章の例9-1では、querySourceのCursor(queryCursor)を作成しています。querySourceは出力を持つため、queryCursorはCompoundCursorです。queryCursorのベースValueCursorは、querySourceを作成した操作のベースSourceであるunitPriceからの値を持ちます。unitPriceの値は、出力によって指定された値です。queryCursorの出力は、prodSelの値を持つValueCursorであり、timeSelの値を持つValueCursorです。
図8-1に、queryCursorの構造を示します。ベースValueCursorおよび2つの出力ValueCursorオブジェクトは、親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から値を取得する例については、第9章を参照してください。
CursorSpecificationオブジェクトは、対応するCursorオブジェクトの動作の一部の側面を指定します。対応するCursorオブジェクトを作成する前に、その動作をCursorSpecificationに指定する必要があります。動作を指定するには、次のCursorSpecificationメソッドを使用します。
setDefaultFetchSize
setExtentCalculationSpecified
setParentEndCalculationSpecified
setParentStartCalculationSpecified
specifyDefaultFetchSizeOnChildren(CompoundCursorSpecificationの場合のみ)
CursorSpecificationには、動作が指定されているかどうかを確認するためのメソッドも含まれています。それらのメソッドを次に示します。
isExtentCalculationSpecified
isParentEndCalculationSpecified
isParentStartCalculationSpecified
CursorSpecificationメソッドを使用して、デフォルトのフェッチ・サイズの設定、エクステントの計算、あるいは親の中での値の開始位置または終了位置の計算を実行した場合、次のCursorメソッドを正常に実行できます。
getExtent
getFetchSize
getParentEnd
getParentStart
setFetchSize
Cursorの動作を指定する例については、第9章を参照してください。フェッチ・サイズの詳細は、「フェッチ・サイズ」を参照してください。Cursorのエクステントの詳細は、「Cursorのエクステントの概要」を参照してください。親Cursorの中での、Cursorの現在の値の開始位置および終了位置の詳細は、「Cursor内での親の開始/終了位置」を参照してください。
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のエクステントを計算するように指定できます。
エクステントの計算が指定されているかどうかを判断できます。
対応するCursorの、親Cursorの中での現在の値の開始位置または終了位置を、Oracle OLAPで計算するように指定できます。親の中での値の開始位置および終了位置がわかっている場合、親Cursorがその値に対して持っている、速く変化する要素の数を判断できます。
対応するCursorの、親の中での現在の値の開始位置または終了位置の計算が指定されているかどうかを判断できます。
CursorSpecificationVisitorを受け入れることができます。
詳細は、「Cursorの位置およびエクステント」および「フェッチ・サイズ」を参照してください。
oracle.olapi.data.sourceパッケージでは、次の表に示すクラスがOracle OLAP Java APIによって定義されます。
| インタフェース | 説明 |
|---|---|
CursorInfoSpecification |
CursorSpecificationオブジェクトのメソッドを指定するインタフェース。 |
CursorSpecification |
CursorInfoSpecificationインタフェースの一部のメソッドを実装する抽象クラス。 |
CompoundCursorSpecification |
1つ以上の出力を持つSourceのCursorSpecification。CompoundCursorSpecificationには、子コンポーネントであるCursorSpecificationオブジェクトが存在する。 |
CompoundInfoCursorSpecification |
CompoundCursorSpecificationオブジェクトのメソッドを指定するインタフェース。 |
ValueCursorSpecification |
値を持ち、出力を持たないSourceのCursorSpecification。 |
ValueCursorInfoSpecification |
ValueCursorSpecificationオブジェクトのインタフェース。 |
Cursorの構造は、そのCursorSpecificationの構造と同じです。各ValueCursorSpecificationまたはCompoundCursorSpecificationは、対応するValueCursorまたはCompoundCursorを持ちます。Cursorから特定の情報または動作を取得できるようにするには、アプリケーションによってCursorが作成される前に、対応するCursorSpecificationのメソッドをコールすることによって、そのアプリケーションでその情報または動作が必要であることを指定する必要があります。
CursorManagerを使用すると、SourceのCursorを作成できます。作成されたCursorオブジェクトのデータのバッファリングは、DataProviderのいずれかのcreateCursorManagerメソッドによって戻されるクラスによって管理されます。
同じCursorManagerから複数のCursorを作成できます。これは、1つの結果セットのデータを、表やグラフなどの異なる形式で表示する場合に有効です。1つのCursorManagerによって作成されたすべてのCursorオブジェクトの仕様(デフォルトのフェッチ・サイズなど)は同じです。仕様が同じであるCursorオブジェクト間では、CursorManagerによって管理されるデータを共有できます。
SQLCursorManagerには、Source用のOracle OLAP SQL Generatorによって生成されたSQLを戻すメソッドがあります。1つ以上のSQLCursorManagerオブジェクトを作成するには、DataProviderのcreateSQLCursorManagerまたはcreateSQLCursorManagersメソッドをコールします。Cursorの作成にSQLCursorManagerは使用しません。代わりに、OLAP Java APIの外部のクラスでSQLCursorManagerによって戻されたSQLを使用するなどの方法で、問合せで指定されたデータを取得します。
アプリケーションでOLAP Java API Templateオブジェクトが使用されており、Templateの状態の変更に従ってそのTemplateによって生成されたSourceの構造が変更された場合、そのSource用のすべてのCursorInfoSpecificationオブジェクトが無効になります。変更されたSourceに対して新しいCursorInfoSpecificationオブジェクトを作成する必要があります。
新しいCursorInfoSpecificationを作成した後、そのSourceの新しいCursorManagerを作成できます。ただし、新しいCursorManagerは、必ずしも作成する必要はありません。既存のCursorManagerのupdateSpecificationメソッドをコールすると、以前のCursorInfoSpecificationを新しいCursorInfoSpecificationに置換できます。その後、CursorManagerから新しいCursorを作成できます。
Cursorには、1つ以上の位置があります。Cursorの現在の位置は、Cursor内で現在アクティブな位置です。Cursorの現在の位置を移動するには、そのCursorのsetPositionまたはnextメソッドをコールします。
Oracle OLAPでは、Cursorに操作(getCurrentValueメソッドのコールなど)を試行しないかぎり、Cursorに設定した位置が検証されません。現在の位置を、負の値か、またはCursor内の位置の数より大きい値に設定してCursor操作を試行すると、CursorによってPositionOutOfBoundsExceptionが発生します。
Cursorのエクステントの詳細は、「Cursorのエクステントの概要」を参照してください。
ValueCursorの現在の位置には、取得可能な1つの値が指定されています。たとえば、prodSel(「Cursorの構造」に示す導出Source)は、製品のディメンションおよび階層的なグループを示すプライマリSourceから3つの製品を選択したものです。prodSelのValueCursorには、3つの要素が存在します。次の例では、ValueCursorの各要素の位置を取得し、その位置の値を表示します。contextオブジェクトには、テキストを表示するメソッドがあります。
// 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から現在の値を取得するその他の例については、第9章を参照してください。
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に、CompoundCursorであるqueryCursorの位置、ベースValueCursorおよび出力を示します。
任意の1セットの出力値によってunitPriceの値が1つのみ指定されるため、queryCursorのValueCursorには位置が1つのみ存在します。querySourceのような問合せの場合、そのCursorのValueCursorの値と位置は、ルート・レベルのCompoundCursorの任意の1つの位置に対して、一度にそれぞれ1つのみになります。
図8-3に、queryCursorからのデータ表示の一例を示します。これは、4つの列および5つの行で構成されたクロス集計ビューです。左の列は日付値です。一番上の行は製品値です。クロス集計の交差している各セルは、その月の製品の価格です。
CompoundCursorでは、ValueCursorオブジェクトの位置が互いに相対的に調整されます。CompoundCursorの現在の位置によって、その子孫ValueCursorオブジェクトの現在の位置が指定されます。例8-2では、queryCursorの位置を設定し、子Cursorオブジェクトの現在の値と位置を取得します。
例8-2 CompoundCursorの位置の設定および現在の値の取得
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());
例8-2の出力は、次のようになります。
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のみです。timeSelのValueCursorの位置が4の場合、prodSelのValueCursorに含まれる位置は2つのみです。
例8-3では、メジャー値の比較に基づいて1つのディメンションの要素を選択して作成される、非対称の結果セットを示します。この例では、例8-1と同じ製品および時間の選択を使用します。製品の販売台数のメジャーのSourceとしてunitsを使用します。これは、製品、時間、売上、チャネルおよび顧客ディメンションによってディメンション化されています。chanSelおよびcustSelオブジェクトは、ディメンションの単一の値の選択です。この例では、選択された時間、チャネルおよび顧客の値について、選択された製品のうち、販売台数が1を超える製品を指定するSource(querySource2)を生成します。querySource2は導出Sourceであるため、この例では現行のTransactionをコミットします。
この例では、querySource2のCursorを作成し、CompoundCursorの位置を通してループし、最初の出力ValueCursorおよびCompoundCursorの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());
例8-3の出力は、次のようになります。
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
指定されたチャネルおよび顧客の選択について、製品および時間の選択のすべての組合せで販売台数が1を超えているとは限らないため、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つあります。
CompoundCursorから取得するデータの表示を効率的に管理するために、現在の遅く変化する値に対して存在する速く変化する値の数を把握することが必要な場合があります。たとえば、クロス集計で、キューブの1つのエッジの値を1つの行に表示する場合、その行に対して表示する列の数を把握する必要がある場合があります。
子Cursorの現在の値に対して存在する速く変化する値の数を判断するには、その現在の値の、親Cursorの中での開始位置および終了位置を検出します。次に示すとおり、終了位置から開始位置を引き、1を足します。
long span = (cursor.getParentEnd() - cursor.getParentStart()) + 1;
これによって、親Cursorの中での、子Cursorの現在の値のスパンが計算されます。このスパンから、現在の値に対して存在する子Cursorの最も速く変化する値の数を判断できます。開始位置と終了位置の計算は、多くの時間およびコンピューティング資源が必要であるため、アプリケーションでその情報が必要な場合にのみこれらの計算を実行するように指定します。
Oracle OLAP Java APIのCursorを使用すると、アプリケーションで、現在表示しているデータのみをクライアント・コンピュータに実際に存在させることができます。Cursorのデータ量を指定する方法の詳細は、「フェッチ・サイズ」を参照してください。
ただし、クライアント・コンピュータ上のデータからは、親Cursorの中での、子Cursorの現在の値が開始または終了する位置を判断することはできません。その情報を取得するには、CursorのgetParentStartおよびgetParentEndメソッドを使用します。
親Cursorの中での子Cursorの値の開始位置および終了位置を計算するようにOracle OLAPに指定するには、そのCursorに対応するCursorSpecificationのsetParentStartCalculationSpecifiedおよびsetParentEndCalculationSpecifiedメソッドをコールします。開始位置と終了位置の計算が指定されているかどうかは、そのCursorSpecificationのisParentStartCalculationSpecifiedまたはisParentEndCalculationSpecifiedメソッドをコールすることによって判断できます。これらの計算を指定する例については、第9章を参照してください。
Cursorのエクステントは、遅く変化する出力に対してそのCursorが含む要素の合計数です。
エクステントの情報は、正確な列数や正確なサイズのスクロールバーを表示する場合などに使用できます。ただし、エクステントの計算は、コストが高くなる場合があります。たとえば、キューブを表すSourceが4つの出力を持ち、各出力には数百の値が含まれる場合があります。出力セットのメジャーのすべてのNULL値と0(ゼロ)値が結果セットから排除される場合、SourceのCompoundCursorのエクステントを計算するには、CompoundCursorを作成する前に結果領域全体を横断する必要があります。エクステントの計算を指定しない場合は、アプリケーションの必要に応じて、Cursorのフェッチ・サイズで指定されたキューブの出力によって定義される要素のセットを横断するのみで済みます。
Oracle OLAPでCursorのエクステントを計算するように指定するには、そのCursorに対応したCursorSpecificationのsetExtentCalculationSpecifiedメソッドをコールします。エクステントの計算が指定されているかどうかは、CursorSpecificationのisExtentCalculationSpecifiedメソッドをコールすることによって判断できます。Cursorのエクステントの計算を指定する例については、第9章を参照してください。
OLAP Java APIのCursorは、Sourceの結果セット全体を表します。ただし、そのCursorがOracle OLAPから一度に取得するのは結果セットの一部のみであるため、それは仮想的なCursorです。CursorManagerは、仮想Cursorを管理し、アプリケーションの必要に応じてOracle OLAPから結果を取得します。CursorManagerで仮想Cursorが管理されることによって、アプリケーションの負荷が大幅に軽減されます。
1回のフェッチ操作でCursorが取得するデータの量は、そのCursorに指定されたフェッチ・サイズによって決定されます。フェッチ・サイズを指定すると、アプリケーションがローカル・コンピュータにキャッシュする必要があるデータの量を制限し、データの表示方法の要件を満たすようにキャッシュをカスタマイズすることによってフェッチの効率を最大限に向上させることができます。
問合せの作成時にParameterおよびパラメータ化Sourceオブジェクトを使用すると、Oracle OLAPによって戻される要素の数を調整することもできます。Parameterオブジェクトの詳細は、第5章「Sourceオブジェクトの理解」を参照してください。パラメータ化Sourceオブジェクトの使用例は、第6章「Sourceメソッドを使用した問合せの作成」を参照してください。
SourceのCursorManagerを作成すると、Oracle OLAPによって、ルートのCursorSpecificationにデフォルトのフェッチ・サイズが指定されます。デフォルトのフェッチ・サイズは、ルート・レベルのCursorSpecificationのsetDefaultFetchSizeメソッドを使用して変更できます。
同じCursorManagerから複数のCursorオブジェクトを作成し、それらのCursorオブジェクトを同時に使用できます。これらのCursorオブジェクトは、個別のデータ・キャッシュを持つのではなく、CursorManagerによって管理されるデータを共有できます。
次の例は、問合せの結果を表とグラフの両方で表示するアプリケーションです。アプリケーションで、SourceのCursorManagerを作成します。このアプリケーションは、同じCursorManagerから、表ビューとグラフ・ビュー用に、2つの別個のCursorオブジェクトを作成します。これらの2つのビューは、同じ問合せを共有し、同じデータを表示しますが、その表示形式は異なります。図8-4に、Source、Cursorオブジェクトおよびビューの関係を示します。