FILEVIEWコマンドは、入力ファイルから一度に1つのレコードを読み取るFILENEXTファンクションとともに機能してデータを処理し、フィールド説明に従ってOracle OLAPディメンションおよび変数にデータを格納するコマンドです。FILENEXTでレコードを読み取ってから、必要に応じて、1つ以上のFILEVIEW文を使用してフィールドを処理します。FILEVIEWには、入力の形式および出力の処理を指定するためにFILEREADと同じ属性があります。
パラメータ
FILEOPENファンクションを事前にコールすることによって読取り用(READモード)で開かれるファイルに割り当てられるファイル・ユニット番号。
フィールド説明は、各入力レコードの1つ以上のフィールドの処理方法を示します。フィールド説明の属性は、入力データの書式化の方法を指定します。FILEVIEWは、書式指定に従って各フィールドを読み取り、入力データを指定されたオブジェクトに割り当てます。データをオブジェクトに直接割り当てることも、式を指定して割当ての前にデータを操作することもできます。1つのフィールド説明によって、1つの入力フィールドのデータを1つのOracle OLAPオブジェクトに割り当てることができます。あるいは、ACROSSキーワードを使用して、入力レコードの複数の値を最も変化の速いディメンションによってディメンション化されている変数に割り当てることもできます。フィールド属性には入力レコードの列番号が含まれるので、入力フィールドを任意の順序で処理できます。
[[pos] ACROSS dim [limit-clause]:] [attribs] object [= exp]
Oracle OLAPがACROSS句によって指定されるフィールドの読取りを開始するレコード内の位置を指定する1つ以上の属性。位置を指定するには、属性FIELD、SPACEおよびCOLUMNを使用します(FILEREADコマンドを参照)。ACROSS句で指定される一連のフィールドが構造化レコードのすぐ次のフィールドまたはルール化レコードのすぐ次のバイトから始まる場合、pos引数はオプションです。
入力レコードにおける1つ以上のデータ・フィールドのディメンションを指定します。FILEVIEWは、dimの現行のステータスの値に従ってフィールドのデータを変数に割り当てます。通常、各フィールド説明で1つの値を処理します。ただし、ACROSSキーワードを使用することにより、現在ステータスにあるディメンション値ごとに1つの入力値を処理できます。ループを複数のアクション文に適用するには、アクション文を山カッコで囲みます。
ACROSS文の構文は次のとおりです。
ACROSS dimension [limit-clause]:
action-statement
limit-clauseの構文は、各種LIMITコマンドにおけるlimit-clause引数の構文(つまり、LIMITコマンドの「TO」などのlimit-type引数の後の構文)と同じです。これらの引数の構文については、LIMITコマンド(値を使用)、LIMITコマンド(LEVELRELを使用)、LIMIT(親リレーションを使用)、LIMITコマンド(関連ディメンションを使用)、LIMITコマンド(NOCONVERTを使用)およびLIMITコマンド(POSLISTを使用)を参照してください。
次の例は、monthの現行のステータスにかかわらず、monthを最近の6つの値に制限します。
ACROSS month last 6: units
レコード内の位置および入力データの形式をOracle OLAPに知らせる1つ以上の属性。(使用可能な属性の説明は、FILEREADコマンドを参照してください。)
入力データの割当て先となるOracle OLAP変数、ディメンションまたはリレーション。= expがない場合、データは暗黙的にオブジェクトに割り当てられます。= expがある場合、データは式に従って処理されてobjectに割り当てられます。
VALUEキーワードを使用して、レコードの特定フィールドの値を表すことができます。VALUEは、使用するFILEREADの属性に従って書式化してファイルのデータを表します。レコードのフィールドが空白の場合、FILEREADはその値をNAとみなします。デフォルトでは、VALUEのデータ型はターゲット・オブジェクトのデータ型です。ただし、属性キーワードによって別のデータ型を指定できます。VALUEは、同じレコードから異なる値を表すために複数回使用できます。次のサンプル・コードに示すように、インスタンスごとに各値を読み取る列を指定します。
sales = if col 1 w 1 text value eq 'A' then col 2 w 8 value - else col 10 w 8 value
この例では、VALUEのデフォルトのデータ型は、ターゲット・オブジェクトsalesのデータ型である10進数です。ただし、VALUEの最初のインスタンスはテキスト式と比較されるので、そのデータ型を指定するためには属性TEXTを使用する必要があります。
フィールド説明のSELECTキーワードは、1つのFILEVIEW文によって様々なタイプのレコード(異なる構造や異なるターゲット・オブジェクトのレコードなど)を処理します。フィールド説明内に、次の構文を使用できます。
SELECT exp -
[WHEN exp action [WHEN exp action ...]] -
[ELSE action]
IF bool-exp THEN action [ELSE action]
DO
field-desc
[field-desc]
...
DOEND
action引数は、次のうちのいずれかです。
NULL(アクションは発生しません)
ネストされたIF文およびSELECT文を含むfield-description
SELECTは最初の式を評価しますが、この式にはVALUEキーワードの呼出しを含めることができ、デフォルトのデータ型はTEXTです。次に、SELECTはその結果をWHEN式と順次比較します。最初に一致が見つかったところで、関連付けられたactionが発生します。一致が見つからない場合、ELSEactionが指定されていれば発生します。
フィールド説明のIFキーワードは、1つのFILEVIEW文によって様々なタイプのレコード(異なる構造や異なるターゲット・オブジェクトのレコードなど)を処理します。フィールド説明内に、次の構文を使用できます。
IF bool-exp THEN action [ELSE action]
actionはSELECTの説明と同じです。
IFはブール式を評価しますが、この式にはVALUEキーワードの呼出しを含めることができます。式がTRUEの場合、IFはTHENアクションを実行し、式がFALSEの場合に、ELSEアクションが指定されていればそのアクションが実行されます。式がNAの場合、アクションは発生しません。
使用上の注意
レコード順序
FILEVIEWは、レコードのフィールドを任意の順序で処理できます。列番号によって明示的にフィールドを特定して、処理する順序にフィールド説明を列記します。また、レコード内のデータに応じて異なる処理を実行するには、同じレコードに対して複数のFILEVIEW文を使用します。
代替OLAP DML文
ファイルのすべてのレコードを複雑なオプションの処理を行わずに同じ方法で処理するには、FILEREAD文を使用すると簡単です。
ディメンション値
フィールド説明のターゲット・オブジェクトがディメンションである場合、ディメンションに値を追加するためにファイルのデータを使用するかどうかを指定できます。ディメンション属性は、次のようにMATCHおよびAPPENDです。
MATCH -- フィールドにある値はすでにディメンションの値である必要があります。FILEVIEWはステータスを一時的にその値に制限します。すでにディメンション値になっているのではない場合、FILEVIEWはエラーを生成します。FILEVIEW文の実行後と実行前のディメンション・ステータスは同じです。
APPEND -- フィールドの値はすでに存在するか新規です。値が存在する場合、FILEVIEWはステータスをその値に制限し、存在しない場合、FILEVIEWは値を追加してからステータスを制限します。FILEVIEWが終了するとディメンションはALLに制限されます。
ディメンションの処理の詳細は、FILEREADコマンドを参照してください。
FILEVIEWでエラーが発生した場合のエラー処理
FILEVIEWがエラーを検出した場合、エラー・トラップおよび適切な処理によって発生したエラーを制御できます。データを互換性のないデータ型に変換しようとした場合、または無効なディメンション値が検出された場合に、エラーが発生します。FILEERRORファンクションを使用すると、発生したエラーのタイプを確認できます。エラーを処理した後は、GOTOを使用してFILEVIEW文に分岐して戻ることができます。
属性リスト
FILEVIEWおよびFILEREADの属性の完全なリスト、NA値の処理、日付値の読取り、多次元データの読取り、NTEXT値の格納、および属性の指定については、FILEREADコマンドを参照してください。
コンポジットを伴うFILEVIEW
FILEREADにおけるコンポジットおよびコンポジットによってディメンション化された変数の説明は、FILEVIEWにも適用されます。
例
例9-133 可変の月数
次のプログラムは、可変の月数に関する販売データを含む入力ファイルを処理します。ファイルには次のレコードがあります。
レコード1 -- タイトル(無視されます)。
レコード2 -- 列ラベル。月名を使用してmonthのステータスを設定します。月数はファイルを処理するまで不明です。
レコード3 -- 列ラベルに下線を引くダッシュ(無視されます)。
レコード4 -- 空白。
レコード5から最後まで -- レコード5には3タイプのレコードがあり、各タイプごとに1行読み取られます。
レコード5のうちの1つのレコード・タイプは、次の表に示す内容の詳細行を表します。
| 列 | 幅 | 書式 | データ |
|---|---|---|---|
| 1 | 8 | シンボリック | 地区名または空白(詳細行で地区名が空白である場合、地区名を含む最新の行によって現行地区が決定される) |
| 10 | 10 | シンボリック | 製品名 |
| 21 | 10 | シンボリック | 最初の月の売上 |
| 33 | 10 | シンボリック | 2番目の月の売上 |
| 45 | レコードの最後まで | シンボリック | その他の月の売上 |
レコード5の別のレコード・タイプは、次の表に示す内容の合計行を表します。
| 列 | 幅 | データ |
|---|---|---|
| 1 | 18 | 空白 |
| 21 | レコードの最後まで | 合計 |
レコード5の最後のレコード・タイプは、次の表に示すように、行セパレータとしてのダッシュまたは等号を含みます。
| 列 | 幅 | データ |
|---|---|---|
| 1 | 18 | 空白 |
| 21 | レコードの最後まで | ダッシュ(--)または等号(==) |
次は、サンプル・ファイルのレコードです。
This is the Title
Jan95 Feb95 Mar95 Apr95
---------- ---------- ---------- ----------
Boston Tents 32,153.52 32,536.30 43,062.75 57,608.39
Canoes 66,013.92 76,083.84 91,748.16 125,594.28
Racquets 52,420.86 56,837.88 58,838.04 69,338.88
Sportswear 53,194.70 58,913.40 62,797.80 67,869.10
Footwear 91,406.82 86,827.32 100,199.46 107,526.66
---------- ---------- ---------- ----------
295,189.82 311,198.74 356,646.21 427,937.31
---------- ---------- ---------- ----------
Atlanta Tents 40,674.20 44,236.55 51,227.06 78,469.37
.
.
.
Footwear 53,284.54 57,331.30 59,144.76 70,516.98
---------- ---------- ---------- ----------
231,780.46 245,812.33 275,622.68 355,784.92
---------- ---------- ---------- ----------
1,813,326 1,985,731 2,185,174 2,638,409
========== ========== ========== ==========
次のプログラムは、ファイルでカバーされている月を確認し、詳細行を読み取り、販売データを適切な地区および月に割り当てます。FILEVIEWが空白である列1から19までを検出すると、プログラムは合計行を無視して下線を引きます。プログラムはデータファイルの名前を引数として受け取ります。
DEFINE salesdata PROGRAM
LD Store Several Months of Sales Data in an Analytic Workspace
PROGRAM
VARIABLE fil.unit INTEGER
VARIABLE flag BOOLEAN
VARIABLE mname TEXT
VARIABLE label TEXT
VARIABLE savedist TEXT
TRAP ON error NOPRINT
PUSH month district
fil.unit = FILEOPEN(ARG(1) READ)
IF FILENEXT(fil.unit) NE YES "Skip Record 1
THEN SIGNAL noread
IF FILENEXT(fil.unit) NE YES "Process Record 2
THEN SIGNAL noread
FILEVIEW fil.unit COLUMN 21 ACROSS month: -
WIDTH 10 mname = JOINLINES( mname VALUE)
LIMIT month TO mname
IF FILENEXT(fil.unit) NE YES "Skip Record 3
THEN SIGNAL noread
IF FILENEXT(fil.unit) NE YES "Skip Record 4
THEN SIGNAL noread
WHILE FILENEXT(fil.unit) "Process Record 5 To End Of File
DO
"Store Value In Local Label Variable
FILEVIEW fil.unit COLUMN 1 WIDTH 18 label
IF label NE NA "Check For NA (Blank Field)
THEN DO "Get District Value If Present
IF EXTCHARS(label, 1, 8) NE ' '
"Set District Status
THEN savedist = BLANKSTRIP(EXTCHARS(label, 1, 8))
FILEVIEW fil.unit -
COLUMN 1 WIDTH 8 district = IF VALUE NE NA THEN -
VALUE ELSE savedist -
COLUMN 10 WIDTH 10 product -
COLUMN 19 ACROSS month: WIDTH 10 SPACE 2 -
SCALE 2 newsales
DOEND
NEXT:
DOEND
FILECLOSE fil.unit
POP month district
RETURN
error:
IF fil.unit EQ NA
THEN SHOW JOINCHARS('Can\'t Open Data File ' ARG(1) '.')
ELSE IF ERRORNAME NE 'attn' AND ERRORNAME NE 'QUIT'
THEN DO
SHOW JOINCHARS('RECORD ' RECNO(fil.unit) ' is invalid.')
GOTO NEXT
DOEND
ELSE IF ERRORNAME EQ 'noread'
THEN DO
SHOW 'File Too Short.'
FILECLOSE fil.unit
DOEND
ELSE DO
SHOW 'Data Import Interrupted.'
FILECLOSE fil.unit
DOEND
POP month district
RETURN
例9-134 追加処理
FILEVIEWが読み取ったディメンション値を表示またはその後の処理のために保存する場合、フィールドを再び読み取ってその値を変数に保存できます。次のプログラムの行は、FILEVIEWが読み取った月の名前を表示します。FILEVIEWコマンドは、列1の月の値をmnameという名前の変数に保存します。
WHILE FILENEXT(fil.unit)
DO
FILEVIEW fil.unit WIDTH 8 month WIDTH 5 INTEGER units -
COLUMN 1 WIDTH 8 mname
SHOW mname PROMPT
DOEND
例9-135 ファンクションとしてのVALUEキーワードの使用
次のような15文字幅の列を持つnumbers.datという名前のディスク・ファイルからデータを読み取ってレポートするとします。
1.0 2.0 3.0 4.0 5.0
-1.0 -2.0 -3.0 -4.0 -5.0
0.0 0.0 1.43900000E+03 1.39900000E+03
次に示すtryという名前のプログラムで、FILEVIEWとともにVALUEキーワードをファンクションとして使用してこのデータを読み取ることができます。ただし、この最初のサンプル・プログラムは機能しません。FILEVIEWコマンドによってフィールドがスキップされます。データがスキップされる原因は、FILEREADが現行レコードからフィールドをフェッチするたびに、列ポインタが更新されてそのフィールドの先を指すことにあります。COLUMN、SPACEまたはFIELD属性を使用して次のフェッチが位置を指定するのではない場合、前のフェッチによって指定されるデフォルトの位置からデータが読み取られます。これは通常は望ましい動作ですが、単一の割当てを実行するために複数のフェッチが必要な場合(たとえば次に示すとおり、同じIF...THEN...ELSEコマンドのブロックにVALUEファンクションが2回コーディングされている場合など)には機能しません。NAMELISTおよびDIRLIST属性は、ディレクトリ内の特定ファイル名の複数バージョンに対して1つの値を返します。また、NAMELIST属性は、ルート・ファイル名は同じでファイル・タイプが異なるディレクトリ内の複数ファイルに対しても1つの値のみを返します。
DEFINE try PROGRAM
PROGRAM
VARIABLE funit INTEGER
DEFINE dvar VARIABLE DECIMAL <year>
PUSH year
LIMIT year TO LAST 5
TRAP ON ERROR
funit=FILEOPEN('numbers.dat' R)
WHILE FILENEXT(funit)
DO
FILEVIEW funit ACROSS year: W 15 TEXT dvar = -
IF FINDCHARS(VALUE, 'e') EQ 0 - "Incorrect Use of Value
THEN CONVERT(VALUE, dec) - "Results in Skipped
ELSE -9999.99 "Fields
REPORT DOWN year dvar
DOEND
error:
FILECLOSE funit
DELETE dvar
POP year
END
次のようにtryプログラムを実行すると、
try
次のように出力で数値がスキップされます。
YEAR DVAR ------------- ---------- Yr93 2.00 Yr94 4.00 Yr95 NA Yr96 -9,999.99 Yr97 -9,999.99 YEAR DVAR ------------- ---------- Yr93 -2.00 Yr94 -4.00 Yr95 NA Yr96 -9,999.99 Yr97 -9,999.99 YEAR DVAR ------------- ---------- Yr93 0.00 Yr94 -9,999.99 Yr95 -9,999.99 Yr96 -9,999.99 Yr97 -9,999.99
これに対し、2番目のVALUEが一定の距離を戻るようにSPACE属性を使用し、同じフィールドが読み取られるようにすると、正常に機能します。前述のサンプル・プログラムでSPACEを使用するには、THEN句を次の句に変更します。
THEN CONVERT(SPACE -15 VALUE, dec) -
ここで、変更したプログラムを実行します。
try
次のように出力されます。
YEAR DVAR ------------- ---------- Yr93 1.00 Yr94 2.00 Yr95 3.00 Yr96 4.00 Yr97 5.00 YEAR DVAR ------------- ---------- Yr93 -1.00 Yr94 -2.00 Yr95 -3.00 Yr96 -4.00 Yr97 -5.00 YEAR DVAR ------------- ---------- Yr93 0.00 Yr94 0.00 Yr95 -9,999.99 Yr96 -9,999.99 Yr97 -9,999.99