FILEVIEWコマンドは、入力ファイルから一度に1つのレコードを読み取るFILENEXTファンクションとともに機能してデータを処理し、フィールド説明に従ってOracle OLAPディメンションおよび変数にデータを格納するコマンドです。FILENEXTでレコードを読み取ってから、必要に応じて、1つ以上のFILEVIEW文を使用してフィールドを処理します。FILEVIEWには、入力の形式および出力の処理を指定するためにFILEREADと同じ属性があります。
構文
FILEVIEW fileunit [field-desc...]
引数
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式と順次比較します。最初に一致が見つかったところで、関連付けられたアクションが発生します。一致が見つからない場合、ELSEアクションが指定されていれば発生します。
フィールド説明の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-132 可変の月数
次のプログラムは、可変の月数に関する販売データを含む入力ファイルを処理します。ファイルには次のレコードがあります。
レコード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-133 追加処理
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-134 ファンクションとしての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