機械翻訳について

9 問合せ結果の取得

この章では、Oracle OLAP Java API Cursorを使用して問合せの結果を取得する方法と、その結果にアクセスする方法について説明します。 この章では、結果の表示メソッドに合せてCursorの動作をカスタマイズするメソッドについても説明します。 Cursorのクラス階層とその関連クラス、および位置、フェッチ・サイズおよびエクステントのCursorの概念の詳細は、「カーソル・クラスおよび概念の理解」を参照してください。

この章では、次の項目について説明します。

9.1 問合せ結果の取得

問合せは、データ・ストアから取得するデータ、およびOracle OLAPがデータに対して実行する計算を指定するOLAP Java API Sourceです。 Cursorは、Sourceで指定された結果セットを取得するオブジェクト(「フェッチ」)です。 SourceCursorを作成するには、次のステップに従います:

  1. MdmObjectからプライマリSourceを取得するか、DataProviderまたはSourceの操作を使用して導出されたSourceを作成します。 Sourceオブジェクトの取得または作成の詳細は、「Sourceオブジェクトの理解」を参照してください。
  2. Sourceが派生Sourceの場合、Sourceを作成したTransactionをコミットします。 Transactionをコミットするには、TransactionProvidercommitCurrentTransactionメソッドをコールします。 Transactionのコミットの詳細は、「TransactionProviderの使用」を参照してください。 SourceがプライマリSourceの場合、Transactionをコミットする必要はありません。
  3. CursorManagerを作成するには、DataProvidercreateCursorManagerメソッドをコールし、そのメソッドをSourceに渡します。
  4. CursorManagercreateCursorメソッドをコールして、Cursorを作成します。

例9-1 Cursorの作成

この例では、querySourceという名前の導出されたSourceCursorを作成します。 この例では、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();

9.1.1 Cursorからの値の取得

Cursorインタフェースは、「現在の位置」の概念をカプセル化し、現在の位置を移動するメソッドを備えています。 ValueCursorおよびCompoundCursorインタフェースは、Cursorインタフェースを拡張します。 Oracle OLAP Java APIには、ValueCursorおよびCompoundCursorインタフェースの実装があります。 CursorManagercreateCursorメソッドをコールすると、Cursorを作成するSourceに応じて、ValueCursorまたはCompoundCursor実装のいずれかが返されます。

ValueCursorは、単一の値セットを持つSourceに対して返されます。 ValueCursorには、現在の位置の値があり、現在の位置で値を取得するためのメソッドがあります。

CompoundCursorは、複数の値のセットを持つSourceに対して作成されます。これは、1つ以上の出力を持つSourceです。 Sourceの各値は、CompoundCursorの子ValueCursorで表されます。 CompoundCursorには、その子Cursorオブジェクトを取得するためのメソッドがあります。

Sourceの構造によって、Cursorの構造が決まります。 Sourceは、ネストされた出力を持つことができます。これは、Sourceの1つ以上の出力自体が出力を含むSourceである場合に発生します。 Sourceにネストされた出力がある場合、そのSourceCompoundCursorには、そのネストされた出力の子CompoundCursorがあります。

CompoundCursorは、それに含まれる子Cursorオブジェクトの位置を調整します。 CompoundCursorの現在の位置は、子Cursorオブジェクトの1つの位置セットを指定します。

出力値が1レベルしかないSourceの例については、「例9-4」を参照してください。 ネストされた出力値を持つSourceの例については、「例9-5」を参照してください。

1つの値セットを表すSourceの例は、製品値を表すMdmPrimaryDimensionなど、MdmDimensiongetSourceメソッドによって返される値です。 そのSourceCursorを作成すると、ValueCursorが返されます。 getCurrentValueメソッドをコールすると、そのValueCursorの現在の位置にある製品値が返されます。

例9-2 ValueCursorからの単一の値の取得

この例では、製品値を表すMdmLevelHierarchyであるmdmProdHierからSourceを取得し、そのSourceに対してCursorを作成します。 この例では、現在の位置をValueCursorの5番目の要素に設定し、Cursorから製品値を取得します。 この例では、CursorManagerを閉じます。 この例では、dpDataProviderです。

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ループとValueCursornextメソッドを使用して、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の例は、メジャーのディメンションから選択した値で指定されたメジャーの値を表すSourceCursorManagercreateCursorメソッドをコールして戻されるものです。

「例9-4」は、unitsという名前のSourceを使用します。このSourceは、販売ユニット数を表すMdmBaseMeasuregetSourceメソッドをコールします。 メジャーのディメンションは、製品、顧客、時間およびチャネルを表すMdmPrimaryDimensionオブジェクトです。 この例では、これらのディメンションのデフォルト階層から選択された値を表すSourceオブジェクトを使用します。 これらのSourceオブジェクトの名前は、prodSel, custSel, timeSelおよびchanSelです。 メジャーおよびディメンション選択を表すSourceオブジェクトの作成は表示されません。

「例9-4」は、ディメンション選択をメジャーに結合し、その結果、unitsForSelectionsという名前のSourceになります。 unitsForSelectionsunitsForSelCursorという名前のCompoundCursorを作成し、ValueCursorのベースとCompoundCursorの出力を取得します。 この場合、各出力はValueCursorです。 出力はListに返されます。 List内の出力の順序は、連続する結合操作によって出力のリストに出力が追加された順序を逆にします。 この例では、dpDataProviderです。

例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に結果を結合します。 結果のSourceunitsForSelectionsは、問合せにネストされた出力があることを示します。これは、複数のレベルの出力があることを意味します。

したがって、この例でunitsForSelectionsに対して作成されるCompoundCursorには、ネストされた出力もあります。 CompoundCursorには子ベースValueCursorがあり、3つの子ValueCursorオブジェクトと1つの子CompoundCursorが出力されます。

「例9-5」は、チャネル・ディメンション値chanSelの選択を、顧客ディメンション値custSelの選択に結合します。 結果はcustByChanSelで、顧客値がベース値として、チャネル値が出力の値として含まれるSourceです。 この例では、製品および時間の値の選択をunitsに結合し、custByChanSelを結合します。 結果の問合せは、unitsForSelectionsで表されます。

この例では、現在のTransactionをコミットし、unitsForSelectionsunitsForSelCursorという名前のCompoundCursorを作成します。

この例では、ベースValueCursorおよび出力をCompoundCursorから取得します。 この例では、dpDataProviderです。

例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");
  }
}

9.2 様々なデータ表示のためのCompoundCursorのナビゲート

CompoundCursorのメソッドを使用すると、CompoundCursor構造を簡単に移動またはナビゲートし、CompoundCursorの子孫ValueCursorから値を取得できます。 OLAPの多次元問合せからのデータは、通常、クロス集計形式または表やグラフとして表示されます。

複数の行および列のデータを表示するには、表示のニーズに応じて、CompoundCursorの異なるレベルで位置をループします。 表などの一部の表示については、親CompoundCursorの位置をループします。 クロス集計などの他の表示では、子Cursorオブジェクトの位置をループします。

表ビューに問合せの結果を表示するには、各行に各出力ValueCursorおよびベースValueCursorからの値が含まれるため、最上位レベル(ルート)のCompoundCursorの位置を決定し、その位置を反復します。 例9-6は、ある時点での結果セットの抜粋です。 単価値を持つメジャーに基づく問合せを表すSourceCursorが作成されます。 そのメジャーのディメンションは、製品ディメンションおよび時間ディメンションです。 プライマリSourceオブジェクトの作成、およびディメンションの導出された選択は表示されません。

この例では、ディメンション値の選択を表すSourceオブジェクトを、メジャーを表すSourceに結合します。 現在のTransactionをコミットしてから、Cursorを作成し、CompoundCursorにキャストします。 この例では、CompoundCursorの位置を設定し、CompoundCursorの12個の位置を反復して、それらの位置で指定された値を出力します。 DataProviderdpです。

例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();

問合せの時間選択に8つの値(2001年と2002年の各カレンダ四半期の最初の月など)があり、製品選択に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の子の位置を繰り返します。

DataProviderdpです。

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を作成し、CursorprintAsCrosstabメソッドに送信します。このメソッドは、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)が選択されています。

DataProviderdpです。 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

9.3 Cursorの動作の指定

Cursorの動作について、次の側面を指定できます。

  • Cursor「取得サイズ」。これは、1回のフェッチ操作中にCursorが取得する結果セットの要素の数です。

  • Oracle OLAPがCursor「範囲」を計算するかどうか。 エクステントは、Cursorの合計位置数です。 CompoundCursorの子Cursorのエクステントは、CompoundCursorの低速な可変出力のいずれかに相対的です。

  • Oracle OLAPが、子Cursorの値が開始または終了する親Cursor内の位置を計算するかどうか。

Cursorの動作を指定するには、そのCursorに指定するCursorSpecificationのメソッドを使用します。 CursorSpecificationは、CursorInfoSpecificationインタフェースを実装します。

DataProvidercreateCursorInfoSpecificationメソッドをコールして、SourceCursorSpecificationを作成します。 CursorSpecificationのメソッドを使用して、必要な特性を設定します。 次に、DataProviderの適切なcreateCursorManagerメソッドをコールして、CursorManagerを作成します。

ノート:

エクステントの計算、または子Cursorの現在の値の親Cursorの開始位置または終了位置の指定は、非常に負荷の高い操作です。 この計算には、多くの時間と計算リソースが使用される場合があります。 アプリケーションに必要な場合にのみ、これらの計算を指定してください。

SourceCursorおよびCursorSpecificationオブジェクトの関係、またはフェッチ・サイズ、エクステントまたはCursor位置の概念の詳細は、「カーソル・クラスおよび概念の理解」を参照してください。

「例9-9」は、Sourceを作成し、SourceCompoundCursorSpecificationを作成し、最上位の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オブジェクトの動作を指定できます。

9.4 エクステントおよび値の開始/終了位置の計算

CompoundCursorによって取得された結果セットの表示を管理するには、子Cursorコンポーネントのエクステントを把握する必要がある場合があります。 また、親CompoundCursorで子Cursorの現在の値が開始される位置を知ることもできます。 Cursorの現在の値の「スパン」を知りたい場合があります。 スパンは、子Cursorの現在の値が占める親Cursorの位置の数です。 値の終了位置から開始位置を引き、さらに1を引くことによって、スパンを計算できます。

Cursorのエクステントを取得したり、親Cursorの値の開始位置または終了位置を取得する前に、Oracle OLAPでエクステントまたはそれらの位置を計算するように指定する必要があります。 これらの計算のパフォーマンスを指定するには、CursorCursorSpecificationのメソッドを使用します。

「例9-10」は、Cursorのエクステントを計算することを指定します。 この例では、「例9-9」CompoundCursorSpecificationを使用します。

例9-10 Cursorのエクステントの計算の指定

rootCursorSpec.setExtentCalculationSpecified(true);

CursorSpecificationのメソッドを使用すると、次の例のように、CursorSpecificationCursorのエクステントの計算を指定するかどうかを判断できます。

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です。 DataProviderdpです。

例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.

9.5 フェッチ・サイズの指定

1回のフェッチ操作中にOracle OLAPがクライアント・アプリケーションに送信するCursorの要素の数は、そのCursorに指定されたフェッチ・サイズによって異なります。 デフォルトのフェッチ・サイズは100です。 フェッチ・サイズを変更するには、SourceのルートCursorでフェッチ・サイズを設定します。

例9-13 フェッチ・サイズの指定

この例では、「例9-9」からCompoundCursorSpecificationからデフォルトのフェッチ・サイズを取得します。 この例では、Cursorを作成し、異なるフェッチ・サイズを設定してから、Cursorのフェッチ・サイズを取得します。 DataProviderdpです。

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.