9 問合せ結果の取得
この章では、Oracle OLAP Java APIのCursor
を使用して問合せの結果を取得する方法およびその結果にアクセスする方法について説明します。 また、結果の表示方法に合せてCursor
の動作をカスタマイズする方法についても説明します。 Cursor
のクラス階層とその関連クラス、およびCursor
の位置、フェッチ・サイズ、エクステントの概念については、「カーソル・クラスと概念の理解」を参照してください。
この章の内容は次のとおりです。
問合せ結果の取得
問合せは、データ・ストアから取得するデータや、そのデータに対してOracle OLAPを使用して実行する任意の計算を指定するOLAP Java APIのSource
です。 Cursor
は、Source
で指定された結果セットを取得するfetchesオブジェクトです。 Source
用のCursor
を作成するには、次の手順を実行します。
MdmObject
からプライマリSource
を取得するか、DataProvider
またはSource
の操作によって派生Source
を作成します。Source
オブジェクトを取得または作成する方法については、「ソース・オブジェクトの理解」を参照してください。Source
が派生したSource
であれば、Source
を作成したTransaction
をコミットします。Transaction
をコミットするには、TransactionProvider
のcommitCurrentTransaction
メソッドをコールします。Transaction
のコミットの詳細については、「TransactionProviderの使用」を参照してください。Source
がプライマリSource
の場合、Transaction
をコミットする必要はありません。DataProvider
のcreateCursorManager
メソッドをコールし、そのメソッドにSource
を渡すことによって、CursorManager
を作成します。CursorManager
のcreateCursor
メソッドをコールして、Cursor
を作成します。
例9-1 Cursorの作成
この例では、querySource
という名前の派生Source
のCursor
を作成します。 この例では、dp
という名前のDataProvider
を使用します。 例では、cursorMngr
という名前のCursorManager
、およびqueryCursor
という名前のCursor
が作成されます。
最後にCursorManager
がクローズされます。 Cursor
の使用が終了したら、CursorManager
をクローズしてリソースを解放する必要があります。
CursorManager cursorMngr = dp.createCursorManager(querySource); Cursor queryCursor = cursorMngr.createCursor(); // Use the Cursor in some way, such as to display the values of it. cursorMngr.close();
Cursorからの値の取得
Cursor
インタフェースは、「現在位置」の概念をカプセル化し、現在の位置を移動するためのメソッドを持っています。 ValueCursor
およびCompoundCursor
インタフェースは、Cursor
インタフェースを拡張します。 Oracle OLAP Java APIには、ValueCursor
およびCompoundCursor
インタフェースの実装が存在します。 CursorManager
のcreateCursor
メソッドをコールすると、Cursor
を作成中のSource
に応じて、ValueCursor
実装またはCompoundCursor
実装が戻されます。
単一の値セットを持つSource
に対して、ValueCursor
が戻されます。 ValueCursor
は、現在の位置に値が含まれており、現在の位置の値を取得するためのメソッドを持ちます。
1つ以上の出力を持つSource
である複数の値セットを持つSource
に対してCompoundCursor
が作成されます。 Source
の各値セットは、CompoundCursor
の子ValueCursor
によって表されます。 CompoundCursor
は、その子Cursor
オブジェクトを取得するためのメソッドを持ちます。
Source
の構造は、Cursor
の構造を決定します。 Source
は、Source
の1つ以上の出力自体が出力を持つSource
である場合に発生するネストされた出力を持つことができます。 Source
にネストされた出力がある場合、そのSource
のCompoundCursor
にはそのネストされた出力の子CompoundCursor
があります。
CompoundCursor
は、それに含まれる子Cursor
オブジェクトの位置を調整します。 CompoundCursor
の現在の位置は、子Cursor
オブジェクトの位置の1セットを指定します。
出力値のレベルが1つのみのSource
の例については、例9-4を参照してください。 ネストされた出力値を持つSource
の例については、例9-5を参照してください。
単一の値セットを表すSource
の例として、MdmDimension
のgetSource
メソッドによって戻されるもの(製品の値を表すMdmPrimaryDimension
など)があります。 そのSource
のCursor
を作成することによって、ValueCursor
が戻されます。 getCurrentValue
メソッドをコールすることによって、ValueCursor
の現在の位置の製品の値が戻されます。
例9-2 ValueCursorからの単一の値の取得
この例では、製品値を表すMdmLevelHierarchy
であるmdmProdHier
からSource
を取得し、そのSource
用のCursor
を作成します。 この例では、現在の位置をValueCursor
の5番目の要素に設定し、Cursor
から製品の値を取得します。 この例では、CursorManager
を閉じます。 例の中のdp
は、DataProvider
です。
Source prodSource = mdmProdHier.getSource(); // Because prodSource is a primary Source, you do not need to // commit the current Transaction. CursorManager cursorMngr = dp.createCursorManager(prodSource); Cursor prodCursor = cursorMngr.createCursor(); // Cast the Cursor to a ValueCursor. ValueCursor prodValues = (ValueCursor) prodCursor; // Set the position to the fifth element of the ValueCursor. prodValues.setPosition(5); // Product values are strings. Get the value at the current position. String value = prodValues.getCurrentString(); // Do something with the value, such as display it. // Close the CursorManager. cursorMngr.close();
例9-3 ValueCursorからのすべての値の取得
この例では、「例9-2」と同じCursor
を使用しています。 この例では、do...while
ループと、ValueCursor
のnext
メソッドを使用して、ValueCursor
の位置を移動します。 next
メソッドは有効な位置で開始し、Cursor
にその他の位置がある場合はtrue
を戻します。 また、現在の位置から次の位置へ移動させます。
例では、位置が、ValueCursor
の最初の位置に設定されています。 例では各位置をループし、getCurrentValue
メソッドを使用して、現在の位置の値を取得します。
// prodValues is the ValueCursor for prodSource. prodValues.setPosition(1); do { println(prodValues.getCurrentValue); } while(prodValues.next());
CompoundCursor
で表される結果セットの値は、CompoundCursor
の子ValueCursor
オブジェクトにあります。 これらの値を取得するには、CompoundCursor
から子ValueCursor
オブジェクトを取得する必要があります。
CompoundCursor
の例としては、(メジャーのディメンションから選択した値によって指定される)メジャーの値を表すSource
用のCursorManager
のcreateCursor
メソッドをコールすることによって戻されるものがあります。
「例9-4」は、販売されたユニットの数を表すMdmBaseMeasure
のgetSource
メソッドを呼び出した結果units
という名前のSource
を使用します。 このメジャーのディメンションは、製品、顧客、時間、およびチャネルを表すMdmPrimaryDimension
オブジェクトです。 この例では、これらのディメンションのデフォルト階層から選択した値を表すSource
オブジェクトを使用します。 これらのSource
オブジェクトの名前は、prodSel
、custSel
、timeSel
、およびchanSel
です。 メジャーとディメンションの選択を表すSource
オブジェクトの作成は示されていません。
「例9-4」はディメンション選択をメジャーに結合し、Source
という名前のunitsForSelections
が生成されます。 unitsForSelections
のunitsForSelCursor
という名前のCompoundCursor
を作成し、ベースValueCursor
とCompoundCursor
の出力を取得します。 この場合、各出力はValueCursor
です。 出力はList
で返されます。 List
の出力の順序は、連続する結合操作によって出力が出力のリストに追加された順序の逆です。 例の中のdp
は、DataProvider
です。
例9-4 CompoundCursorからのValueCursorオブジェクトの取得
Source unitsForSelections = units.join(prodSel) .join(custSel) .join(timeSel) .join(chanSel); // Commit the current Transaction (code not shown). // Create a Cursor for unitsForSelections. CursorManager cursorMngr = dp.createCursorManager(unitsForSelections); CompoundCursor unitsForSelCursor = (CompoundCursor) cursorMngr.createCursor(); // Get the base ValueCursor. ValueCursor specifiedUnitsVals = unitsForSelCursor.getValueCursor(); // Get the outputs. List outputs = unitsForSelCursor.getOutputs(); ValueCursor chanSelVals = (ValueCursor) outputs.get(0); ValueCursor timeSelVals = (ValueCursor) outputs.get(1); ValueCursor custSelVals = (ValueCursor) outputs.get(2); ValueCursor prodSelVals = (ValueCursor) outputs.get(3); // You can now get the values from the ValueCursor objects. // When you have finished using the Cursor objects, close the CursorManager. cursorMngr.close();
「例9-5」は「例9-4」と同じ単位を使用しますが、ディメンションの選択を異なる方法で結合します。 「例9-5」はディメンション選択の2つを一緒に結合します。 その後、単一ディメンション選択をメジャーに結合して生成されたSource
に結果を結合します。 結果として得られるSource
、unitsForSelections
は、問合せにネストされた出力があることを表します。これは、複数レベルの出力を持つことを意味します。
したがって、この例でunitsForSelections
用に作成するCompoundCursor
には、ネストされた出力も含まれています。 CompoundCursor
は子ベースValueCursor
を持ち、出力として3つの子ValueCursor
オブジェクトと1つの子CompoundCursor
を持っています。
例9-5では、チャネル・ディメンション値の選択(chanSel
)が顧客ディメンション値の選択(custSel
)に結合されます。 その結果は、ベース値として顧客の値、出力値としてチャネルの値を持つSource
(custByChanSel
)です。 製品および時間の値の選択は、units
に結合され、その後custByChanSel
に結合されます。 これによって生成される問合せは、unitsForSelections
によって表されます。
例では、現行のTransaction
をコミットし、unitsForSelections
に対してunitsForSelCursor
というCompoundCursor
を作成します。
例では、ベースValueCursor
およびCompoundCursor
からの出力が取得されます。 例の中のdp
は、DataProvider
です。
例9-5 ネストされた出力を持つCompoundCursorからの値の取得
Source custByChanSel = custSel.join(chanSel); Source unitsForSelections = units.join(prodSel) .join(timeSel) .join(custByChanSel); // Commit the current Transaction (code not shown). // Create a Cursor for unitsForSelections. CursorManager cursorMngr = dp.createCursorManager(unitsForSelections); Cursor unitsForSelCursor = cursorMngr.createCursor(); // Send the Cursor to a method that does different operations // depending on whether the Cursor is a CompoundCursor or a // ValueCursor. printCursor(unitsForSelCursor); cursorMngr.close(); // The remaining code of someMethod is not shown. // The following code is in from the CursorPrintWriter class. // The printCursor method has a do...while loop that moves through the positions // of the Cursor passed to it. At each position, the method prints the number of // the iteration through the loop and then a colon and a space. The output // object is a PrintWriter. The method calls the private _printTuple method and // then prints a new line. A "tuple" is the set of output ValueCursor values // specified by one position of the parent CompoundCursor. The method prints one // line for each position of the parent CompoundCursor. private void printCursor(Cursor rootCursor) { int i = 1; do { print(i++ + ": "); _printTuple(rootCursor); println(); flush(); } while(rootCursor.next()); } // If the Cursor passed to the _printTuple method is a ValueCursor, then // the method prints the value at the current position of the ValueCursor. // If the Cursor passed in is a CompoundCursor, then the method gets the // outputs of the CompoundCursor and iterates through the outputs, // recursively calling itself for each output. The method then gets the // base ValueCursor of the CompoundCursor and calls itself again. private void _printTuple(Cursor cursor) { if(cursor instanceof CompoundCursor) { CompoundCursor compoundCursor = (CompoundCursor)cursor; // Put an open parenthesis before the value of each output. print("("); Iterator iterOutputs = compoundCursor.getOutputs().iterator(); Cursor output = (Cursor)iterOutputs.next(); _printTuple(output); while(iterOutputs.hasNext()) { // Put a comma after the value of each output. print(","); _printTuple((Cursor)iterOutputs.next()); } // Put a comma after the value of the last output. print(","); // Get the base ValueCursor. _printTuple(compoundCursor.getValueCursor()); // Put a close parenthesis after the base value to indicate // the end of the tuple. print(")"); } else if(cursor instanceof ValueCursor) { ValueCursor valueCursor = (ValueCursor) cursor; if (valueCursor.hasCurrentValue()) print(valueCursor.getCurrentValue()); else // If this position has a null value. print("NA"); } }
様々なデータ表示のためのCompoundCursorのナビゲート
CompoundCursor
のメソッドを使用すると、CompoundCursor
構造を簡単に移動またはナビゲートし、CompoundCursor
のValueCursor
子孫から値を取得できます。 OLAPの多次元問合せからのデータは、通常、クロス集計形式または表やグラフとして表示されます。
複数の行および列にデータを表示するには、表示の要件に応じて、様々なレベルのCompoundCursor
の位置をループします。 表などの一部の表示方法の場合、親CompoundCursor
の位置をループします。 クロス集計などのその他の表示方法の場合、子Cursor
オブジェクトの位置をループします。
各行に各出力ValueCursor
およびベースValueCursor
からの値が含まれる問合せの結果を表形式で表示するには、最上位のルート(CompoundCursor
)の位置を決定し、その位置を反復処理します。 例9-6は、ある時点での結果セットの抜粋です。 製造コストの値を持つメジャーに基づいた問合せを表すSource
用のCursor
が作成されます。 そのメジャーのディメンションは、製品ディメンションおよび時間ディメンションです。 プライマリSource
オブジェクトの作成、およびディメンションの導出された選択については、ここでは示しません。
この例では、ディメンション値の選択を表すSource
オブジェクトを、メジャーを表すSource
に結合します。 現行のTransaction
がコミットされ、次にCursor
が作成され、それがCompoundCursor
にキャストされます。 この例では、CompoundCursor
の位置を設定し、CompoundCursor
の12個の位置を反復し、それらの位置で指定された値を出力します。 DataProvider
はdp
です。
例9-6 表ビュー用のナビゲート
Source unitPriceByMonth = unitPrice.join(productSel) .join(timeSel); // Commit the current Transaction (code not shown). // Create a Cursor for unitPriceByMonth. CursorManager cursorMngr = dp.createCursorManager(unitPriceByMonth); CompoundCursor rootCursor = (CompoundCursor) cursorMngr.createCursor(); // Determine a starting position and the number of rows to display. int start = 7; int numRows = 12; println("Month Product Unit Price"); println("------- -------- ----------"); // Iterate through the specified positions of the root CompoundCursor. // Assume that the Cursor contains at least (start + numRows) positions. for(int pos = start; pos < start + numRows; pos++) { // Set the position of the root CompoundCursor. rootCursor.setPosition(pos); // Print the local values of the output and base ValueCursors. // The getLocalValue method gets the local value from the unique // value of a dimension element. String timeValue = ((ValueCursor)rootCursor.getOutputs().get(0)) .getCurrentString(); String timeLocVal = getLocalValue(timeValue); String prodValue = ((ValueCursor)rootCursor.getOutputs().get(1)) .getCurrentString(); String prodLocVal = getLocalValue(prodValue); Object price = rootCursor.getValueCursor().getCurrentValue(); println(timeLocVal + " " + prodLocVal + " " + price); } cursorMngr.close();
問合せの時間選択に、2001年と2002年の各暦四半期の最初の月などの8つの値があり、製品選択に3つの値がある場合、unitPriceByMonth
問合せの結果セットには24の位置があります。 この例では、CompoundCursor
の位置7〜18で指定された値を持つ次の表が表示されます。
Month Product Unit Price ------- -------- ---------- 2001.07 ENVY ABM 2892.18 2001.07 ENVY EXE 3155.91 2001.07 ENVY STD 2505.57 2001.10 ENVY ABM 2856.86 2001.10 ENVY EXE 3105.53 2001.10 ENVY STD 2337.3 2002.01 ENVY ABM 2896.77 2002.01 ENVY EXE 3008.95 2002.01 ENVY STD 2140.71 2002.04 ENVY ABM 2880.39 2002.04 ENVY EXE 2953.96 2002.04 ENVY STD 2130.88
例9-7 単一ページのクロス集計ビュー用のナビゲート
この例では、「例9-6」と同じ問合せを使用しています。 クロス・タブ・ビューでは、最初の行は列見出しです。この例のprodSel
の値です。 prodSel
ディメンションの選択は、ディメンションをディメンション選択項目に結合する操作の結果である出力リストの最後の出力であるため、prodSel
の出力はより速く変化する出力です。 残りの行は行ヘッダーで始まります。 行見出しは、変化の遅い出力からの値です。これはtimeSel
です。 列見出しの下の行の残りの位置には、ディメンション値のセットによって指定されたunitPrice
値が含まれます。 クロス集計ビューで問合せの結果を表示するには、最上位のCompoundCursor
の子の位置を反復処理します。
DataProvider
はdp
です。
Source unitPriceByMonth = unitPrice.join(productSel) .join(timeSel); // Commit the current Transaction (code not shown). // Create a Cursor for unitPriceByMonth. CursorManager cursorMngr = dp.createCursorManager(unitPriceByMonth); CompoundCursor rootCursor = (CompoundCursor) cursorMngr.createCursor(); // Get the outputs and the ValueCursor objects. List outputs = rootCursor.getOutputs(); // The first output has the values of timeSel, the slower varying output. ValueCursor rowCursor = (ValueCursor) outputs.get(0); // The second output has the faster varying values of productSel. ValueCursor columnCursor = (ValueCursor) outputs.get(1); // The base ValueCursor has the values from unitPrice. ValueCursor unitPriceValues = rootCursor.getValueCursor(); // Display the values as a crosstab. println(" PRODUCT"); println(" ---------------------------------"); print("Month "); do { String value = ((ValueCursor) columnCursor).getCurrentString(); print(getContext().getLocalValue(value) + " "); } while (columnCursor.next()); println("\n------- -------- -------- --------"); // Reset the column Cursor to its first element. columnCursor.setPosition(1); do { // Print the row dimension values. String value = ((ValueCursor) rowCursor).getCurrentString(); print(getContext().getLocalValue(value) + " "); // Loop over columns. do { // Print data value. print(unitPriceValues.getCurrentValue() + " "); } while (columnCursor.next()); println(); // Reset the column Cursor to its first element. columnCursor.setPosition(1); } while (rowCursor.next()); cursorMngr.close();
次のクロス集計ビューは、unitPriceByMonth
問合せによって指定された結果セットからの値を表示したものです。 最初の行は、製品の値が右側の3つの列に含まれていることを示します。 3行目は、最初の列に月の値が含まれ、その右にある3つの各列に製品の値が含まれていることを示します。 残りの行では、左の列に月の値が、その横には指定された月および製品のunitsメジャーのデータ値が示されています。
PRODUCT --------------------------------- Month ENVY ABM ENVY EXE ENVY STD ------- -------- -------- -------- 2001.01 3042.22 3223.28 2426.07 2001.04 3026.12 3107.65 2412.42 2001.07 2892.18 3155.91 2505.57 2001.10 2856.86 3105.53 2337.30 2002.01 2896.77 3008.95 2140.71 2002.04 2880.39 2953.96 2130.88 2002.07 2865.14 3002.34 2074.56 2002.10 2850.88 2943.96 1921.62
例9-8 複数ページのクロス集計ビュー用のナビゲート
この例では、販売された単位の数値に基づいてSource
を作成します。 メジャーのディメンションは、顧客、製品、時間およびチャネルです。 それらのディメンション用のSource
オブジェクトは、ディメンション値の選択を表します。 これらのSource
オブジェクトの作成については、ここでは示しません。
ディメンションの選択をメジャーのSource
に結合することによって作成される問合せは、その出力値によって指定される販売台数の値を表します。
この例では、問合せのCursor
を作成し、Cursor
をprintAsCrosstab
メソッドに送信します。このメソッドは、クロス・タブ内のCursor
から値を出力します。 このメソッドは、ページ、列、および行の値を出力する他のメソッドを呼び出します。
Cursor
の最も速く変化する出力は、製品の選択で、3つの値(製品項目ENVY ABM、ENVY EXEおよびENVY STD)が存在します。 製品の値はクロス集計の列ヘッダーです。 2番目に速く変化する出力は、顧客の選択で、3つの値(顧客COMP SERV TOK、COMP WHSE LONおよびCOMP WHSE SD)が存在します。 これらの3つの値は行ヘッダーです。 ページ・ディメンションには、時間の3つの値(月2000.01、2000.02および2000.03)およびチャネルの1つの値(直販チャネルを表すDIR)が選択されています。
DataProvider
はdp
です。 getLocalValue
メソッドは、一意のディメンション値からローカル値を取得します。
// In someMethod. Source unitsForSelections = units.join(prodSel) .join(custSel) .join(timeSel) .join(chanSel); // Commit the current Transaction (code not shown). // Create a Cursor for unitsForSelections. CursorManager cursorMngr = dp.createCursorManager(unitsForSelections); CompoundCursor unitsForSelCursor = (CompoundCursor) cursorMngr.createCursor(); // Send the Cursor to the printAsCrosstab method. printAsCrosstab(unitsForSelCursor); cursorMngr.close(); // The remainder of the code of someMethod is not shown. private void printAsCrosstab(CompoundCursor rootCursor) { List outputs = rootCursor.getOutputs(); int nOutputs = outputs.size(); // Set the initial positions of all outputs. Iterator outputIter = outputs.iterator(); while (outputIter.hasNext()) ((Cursor) outputIter.next()).setPosition(1); // The last output is fastest-varying; it represents columns. // The next to last output represents rows. // All other outputs are on the page. Cursor colCursor = (Cursor) outputs.get(nOutputs - 1); Cursor rowCursor = (Cursor) outputs.get(nOutputs - 2); ArrayList pageCursors = new ArrayList(); for (int i = 0 ; i < nOutputs - 2 ; i++) { pageCursors.add(outputs.get(i)); } // Get the base ValueCursor, which has the data values. ValueCursor dataCursor = rootCursor.getValueCursor(); // Print the pages of the crosstab. printPages(pageCursors, 0, rowCursor, colCursor, dataCursor); } // Prints the pages of a crosstab. private void printPages(List pageCursors, int pageIndex, Cursor rowCursor, Cursor colCursor, ValueCursor dataCursor) { // Get a Cursor for this page. Cursor pageCursor = (Cursor) pageCursors.get(pageIndex); // Loop over the values of this page dimension. do { // If this is the fastest-varying page dimension, print a page. if (pageIndex == pageCursors.size() - 1) { // Print the values of the page dimensions. printPageHeadings(pageCursors); // Print the column headings. printColumnHeadings(colCursor); // Print the rows. printRows(rowCursor, colCursor, dataCursor); // Print a couple of blank lines to delimit pages. println(); println(); } // If this is not the fastest-varying page, recurse to the // next fastest-varying dimension. else { printPages(pageCursors, pageIndex + 1, rowCursor, colCursor, dataCursor); } } while (pageCursor.next()); // Reset this page dimension Cursor to its first element. pageCursor.setPosition(1); } // Prints the values of the page dimensions on each page. private void printPageHeadings(List pageCursors) { // Print the values of the page dimensions. Iterator pageIter = pageCursors.iterator(); while (pageIter.hasNext()) { String value = ((ValueCursor) pageIter.next()).getCurrentString(); println(getLocalValue(value)); } println(); } // Prints the column headings on each page. private void printColumnHeadings(Cursor colCursor) { do { print("\t"); String value = ((ValueCursor) colCursor).getCurrentString(); print(getLocalValue(value)); } while (colCursor.next()); println(); colCursor.setPosition(1); } // Prints the rows of each page. private void printRows(Cursor rowCursor, Cursor colCursor, ValueCursor dataCursor) { // Loop over rows. do { // Print row dimension value. String value = ((ValueCursor) rowCursor).getCurrentString(); print(getLocalValue(value)); print("\t"); // Loop over columns. do { // Print data value. print(dataCursor.getCurrentValue()); print("\t"); } while (colCursor.next()); println(); // Reset the column Cursor to its first element. colCursor.setPosition(1); } while (rowCursor.next()); // Reset the row Cursor to its first element. rowCursor.setPosition(1); }
この例では、クロス・タブとして書式設定された次の値が表示されます。 ディメンションのローカル値を識別するために、ページ・ヘッダー、列ヘッダーおよび行ヘッダーが表示されます。
Channel DIR Month 2001.01 Product ------------------------------ Customer ENVY ABM ENVY EXE ENVY STD ------------- -------- -------- -------- COMP WHSE SD 0 0 1 COMP SERV TOK 2 4 2 COMP WHSE LON 1 1 2 Channel DIR Month 2000.02 Product ------------------------------ Customer ENVY ABM ENVY EXE ENVY STD ------------- -------- -------- -------- COMP WHSE SD 1 1 1 COMP SERV TOK 5 6 6 COMP WHSE LON 1 2 2 Channel DIR Month 2000.03 Product ------------------------------ Customer ENVY ABM ENVY EXE ENVY STD ------------- -------- -------- -------- COMP WHSE SD 0 2 2 COMP SERV TOK 2 0 2 COMP WHSE LON 0 2 3
Cursorの動作の指定
-
Cursor
の「サイズを取得」は、Cursor
が1回のフェッチ操作中に取得する結果セットの要素の数です。 -
Oracle OLAPによって、
Cursor
のエクステントを計算するかどうか。 エクステントは、Cursor
の位置の合計数です。CompoundCursor
の子Cursor
の範囲は、CompoundCursor
のより遅い可変出力のいずれかとの相対的なものです。 -
子
Cursor
の値が開始または終了する親Cursor
内の位置をOracle OLAPが計算するかどうか。
Cursor
の動作を指定するには、そのCursor
に指定するCursorSpecification
のメソッドを使用します。 CursorSpecification
は、CursorInfoSpecification
インタフェースを実装します。
Source
のCursorSpecification
を作成するには、DataProvider
のcreateCursorInfoSpecification
メソッドをコールします。 必要な特性を設定するには、CursorSpecification
のメソッドを使用します。 次に、DataProvider
の適切なcreateCursorManager
メソッドをコールしてCursorManager
を作成します。
注意:
子Cursor
の現在の値の親Cursor
のエクステントまたは開始位置または終了位置の計算を指定することは、非常に高価な操作になります。 この計算には、多くの時間と計算リソースが使用される場合があります。 アプリケーションに必要な場合にのみ、これらの計算を指定してください。
Source
、Cursor
、およびCursorSpecification
オブジェクトの関係、またはフェッチ・サイズ、エクステント、またはCursor
の位置の概念の詳細については、「カーソル・クラスと概念の理解」を参照してください。
「例9-9」はSource
を作成し、Source
用のCompoundCursorSpecification
を作成し、最上位のCompoundCursorSpecification
から子CursorSpecification
オブジェクトを取得します。
例9-9 SourceのCursorSpecificationオブジェクトの取得
Source unitsForSelections = units.join(prodSel) .join(custSel) .join(timeSel) .join(chanSel); // Commit the current Transaction (code not shown). // Create a CompoundCursorSpecification for unitsForSelections. CompoundCursorSpecification rootCursorSpec = (CompoundCursorSpecification) dp.createCursorInfoSpecification(unitsForSelections); // Get the ValueCursorSpecification for the base values. ValueCursorSpecification baseValueSpec = rootCursorSpec.getValueCursorSpecification(); // Get the ValueCursorSpecification objects for the outputs. List outputSpecs = rootCursorSpec.getOutputs(); ValueCursorSpecification chanSelValCSpec = (ValueCursorSpecification) outputSpecs.get(0); ValueCursorSpecification timeSelValCSpec = (ValueCursorSpecification) outputSpecs.get(1); ValueCursorSpecification prodSelValCSpec = (ValueCursorSpecification) outputSpecs.get(2); ValueCursorSpecification custSelValCSpec = (ValueCursorSpecification) outputSpecs.get(3);
CursorSpecification
オブジェクトを取得した後は、そのメソッドを使用して、それに対応しているCursor
オブジェクトの動作を指定できます。
エクステントおよび値の開始/終了位置の計算
CompoundCursor
によって取得された結果セットの表示を管理するために、その子Cursor
コンポーネントのエクステントを把握しておくことが必要な場合があります。 親CompoundCursor
の中で子Cursor
の現在の値が開始される位置も把握しておくことが必要な場合があります。 子Cursor
の現在の値のスパンを知っておくことが必要な場合もあります。 スパンは、子Cursor
の現在の値が占める親Cursor
の位置の数です。 値の終了位置から開始位置を引き、さらに1を引くことによって、スパンを計算できます。
Cursor
の範囲を取得したり、親Cursor
の値の開始位置または終了位置を取得する前に、Oracle OLAPでエクステントまたはその位置を計算するように指定する必要があります。 これらの計算の実行を指定するには、Cursor
用のCursorSpecification
のメソッドを使用します。
例9-10では、Cursor
のエクステントの計算を指定しています。 この例では、例9-9のCompoundCursorSpecification
を使用します。
例9-10 Cursorのエクステントの計算の指定
rootCursorSpec.setExtentCalculationSpecified(true);
次の例のように、CursorSpecification
のメソッドを使用して、CursorSpecification
がCursor
のエクステントの計算を指定するかどうかを判断できます。
boolean isSet = rootCursorSpec.isExtentCalculationSpecified();
「例9-11」は、親Cursor
内の子Cursor
の現在の値の開始位置と終了位置を指定します。 この例では、例9-9のCompoundCursorSpecification
を使用します。
例9-11 親の中での開始/終了位置の計算の指定
// Get the List of CursorSpecification objects for the outputs. // Iterate through the list, specifying the calculation of the extent // for each output CursorSpecification. Iterator iterOutputSpecs = rootCursorSpec.getOutputs().iterator(); while(iterOutputSpecs.hasNext()) { ValueCursorSpecification valCursorSpec = (ValueCursorSpecification)iterOutputSpecs.next(); valCursorSpec.setParentStartCalculationSpecified(true); valCursorSpec.setParentEndCalculationSpecified(true); }
次の例のように、CursorSpecification
のメソッドを使用して、CursorSpecification
が親Cursor
内の子Cursor
の現在の値の開始位置または終了位置の計算を指定するかどうかを判断できます。
Iterator iterOutputSpecs = rootCursorSpec.getOutputs().iterator(); ValueCursorSpecification valCursorSpec = (ValueCursorSpecification)iterOutputSpecs.next(); while(iterOutputSpecs.hasNext()) { if (valCursorSpec.isParentStartCalculationSpecified()) // Do something. if (valCursorSpec.isParentEndCalculationSpecified()) // Do something. valCursorSpec = (ValueCursorSpecification) iterOutputSpecs.next(); }
「例9-12」は、CompoundCursor
の2つの出力の子Cursor
の現在の値の親CompoundCursor
内の位置のスパンを決定します。 この例では、例9-8のunitForSelections
Source
を使用します。
例では、時間および製品の選択の現在の値の開始および終了位置が取得され、親Cursor
の中でのこれらの値のスパンが計算されます。 親は、ルートCompoundCursor
です。 DataProvider
はdp
です。
例9-12 値の親の中での位置のスパンの計算
Source unitsForSelections = units.join(prodSel) .join(custSel) .join(timeSel) .join(chanSel); // Commit the current Transaction (code not shown). // Create a CompoundCursorSpecification for unitsForSelections. CompoundCursorSpecification rootCursorSpec = (CompoundCursorSpecification) dp.createCursorInfoSpecification(unitsForSelections); // Get the CursorSpecification objects for the outputs. List outputSpecs = rootCursorSpec.getOutputs(); ValueCursorSpecification timeSelValCSpec = (ValueCursorSpecification)outputSpecs.get(1); // Output for time. ValueCursorSpecification prodSelValCSpec = (ValueCursorSpecification)outputSpecs.get(3); // Output for product. // Specify the calculation of the starting and ending positions. timeSelValCSpec.setParentStartCalculationSpecified(true); timeSelValCSpec.setParentEndCalculationSpecified(true); prodSelValCSpec.setParentStartCalculationSpecified(true); prodSelValCSpec.setParentEndCalculationSpecified(true); // Create the CursorManager and the Cursor. CursorManager cursorMngr = dp.createCursorManager(unitsForSelections, 100, rootCursorSpec); CompoundCursor rootCursor = (CompoundCursor) cursorMngr.createCursor(); // Get the child Cursor objects. ValueCursor baseValCursor = cursor.getValueCursor(); List outputs = rootCursor.getOutputs(); ValueCursor chanSelVals = (ValueCursor) outputs.get(0); ValueCursor timeSelVals = (ValueCursor) outputs.get(1); ValueCursor custSelVals = (ValueCursor) outputs.get(2); ValueCursor prodSelVals = (ValueCursor) outputs.get(3); // Set the position of the root CompoundCursor. rootCursor.setPosition(15); // Get the values at the current position and determine the span // of the values of the time and product outputs. print(chanSelVals.getCurrentValue() + ", "); print(timeSelVals.getCurrentValue() + ",\n "); print(custSelVals.getCurrentValue() + ", "); print(prodSelVals.getCurrentValue() + ", "); print(baseValCursor.getCurrentValue()); println(); // Determine the span of the values of the two fastest-varying outputs. long span; span = (prodSelVals.getParentEnd() - prodSelVals.getParentStart()) +1); println("\nThe span of " + prodSelVals.getCurrentValue() + " at the current position is " + span + ".") span = (timeSelVals.getParentEnd() - timeSelVals.getParentStart()) +1); println("The span of " + timeSelVals.getCurrentValue() + " at the current position is " + span + ".") cursorMngr.close();
この例によって表示されるテキストは、次のとおりです。
CHANNEL_PRIMARY::CHANNEL::DIR, CALENDAR_YEAR::MONTH::2000.02, SHIPMENTS::SHIP_TO::COMP SERV TOK, PRODUCT_PRIMARY::ITEM::ENVY STD, 6.0 The span of PRODUCT_PRIMARY::ITEM::ENVY STD at the current position is 1. The span of CALENDAR_YEAR::MONTH::2000.02 at the current position is 9.
フェッチ・サイズの指定
フェッチ操作中にOracle OLAPがクライアント・アプリケーションに送信するCursor
の要素数は、そのCursor
に指定されたフェッチ・サイズによって異なります。 デフォルトのフェッチ・サイズは100です。 フェッチ・サイズを変更するには、Source
のルートCursor
のフェッチ・サイズを設定します。
例9-13 フェッチ・サイズの指定
この例では、CompoundCursorSpecification
から「例9-9」のデフォルト・フェッチ・サイズを取得します。 この例では、Cursor
を作成し、その上に異なるフェッチ・サイズを設定してから、Cursor
のフェッチ・サイズを取得します。 DataProvider
はdp
です。
println("The default fetch size is " + rootCursorSpec.getDefaultFetchSize() + "."); Source source = rootCursorSpec.getSource(); CursorManager cursorMngr = dp.createCursorManager(source); Cursor rootCursor = cursorMngr.createCursor(); rootCursor.setFetchSize(10); println("The fetch size is now " + rootCursor.getFetchSize()) + ".";
この例では、次のテキストが表示されます。
The default fetch size is 100. The fetch size is now 10.