2016-10-26 6 views
-2

UTL_FILEを使用して複数行ファイルを解析するにはどうすればよいですか?以下の例のスニペットでは、 '1'で始まる行はファイルヘッダーです(ファイルごとに1つ)。 '8'で始まる行は、トランザクションごとに1つずつです。 '9'で始まる行はファイルごとに1つです。Oracleのマルチラインフラットファイルの解析

私は、1)ファイル行を読み、2)トランザクションの開始と終了を区別できるロジックが必要です。 1行につき、Oracleには、異なる値を区別するためのinstrとsubstrがあります。

どのような提案も歓迎されます!御時間ありがとうございます。

1TreasuryPart 201610031830MEMO                                                                   
53336  Bank1Base0000001                                                                    
650 3100000126   1-30-00010-00  000002126100000000000000021261USD20161003RAYMOND SOLIS   [email protected]     205-888-9900       20161003020030000001     WEBENRAPC34560000000000     WEB      
800000000010000000212610000000000000000001                                                                 
53336  Bank1Base0000002                                                                    
800000000000000000000000000000000000000002                                                                 
53343  ToddMUD  0000001                                                                    
800000000000000000000000000000000000000001                                                                 
53343  ToddMUD  0000002                                                                    
800000000000000000000000000000000000000002                                                                 
53351  DenisTM  0000001                                                                    
650 3100000128   7779026   000004000000000000000000080000USD20161003Denis Pellerin  [email protected]            405-922-2116  20161003100421000001     WEBUNEAPC34560000000000     WEB      
650 3100000128   7779026   000004000000000000000000080000USD20161003Denis Pellerin  [email protected]            405-922-2116  20161003100421000002     WEBUNEAPC34560000000000     WEB      
800000000020000000800000000000000000000001                                                                 
53351  DenisTM  0000002                                                                    
800000000000000000000000000000000000000002                                                                 
9000006000000000003000000101261000000000000                                                                 
+0

あなたは何を試しましたか、どのような問題がありますか? 'SQL * Loader'ではなく' utl_file'を使いたいと言うので、 'get_line'を呼び出してファイルから行を読み込む方法を知っていると思います。 'substr'と' instr'を使って、その行の最初の文字を得ることができます。既に1と5を読んでいるので、トランザクション行を読み込んでいる(そしてそれらの行を解析する方法を知る)ために、ある種のローカル状態変数が必要です。 –

+0

私は5の任意の数のための1つのレコードの1レコードを定義しました6の任意の数の1レコード、8の任意の数の1レコードと9の1レコード。私もutl_file.fgetattrを行っているファイルの有無を確認してください。私はレコードごとのレコード変数を解析しています。私が言及したように、最初の行から次の行への読み方、そしてトランザクションAがどこで終了し、トランザクションBが開始されるのか把握するときに悩まされます。上記の例では、5と8の間に2つの連続した6を持つことは有効なケースです。 – QuickDrawMcgraw

+0

「最初の行から次の行へ読む」という意味はわかりません。ファイルから次の行を取得するために単に 'utl_file.get_line'を呼び出すと解釈します。それは本当にあなたが求めているものではないようです。私は、トランザクションを読むためには、あなたが8を持っているまであなたが5に遭遇したときにループ内で 'utl_file.get_line'を呼び出すと仮定しますが、それはあなたのファイルの構造を推測しています。 –

答えて

0

私はあなたが探しているものはよく分かりません。投稿コードは、私たちが推測していないように常に役立ちます。私はあなたがこのような何かをしたいと思うだろうと思うだろう別の手続きがラインのそれぞれのタイプを解析するために定義されている。

declare 
    l_file utl_file.file_type; 
    l_line varchar2(4000); 
    l_in_transaction boolean := false; 
begin 
    l_file := utl_file.fopen(<<parameters>>); 

    loop 
    utl_file.get_line(l_file, l_line); 
    if(substr(l_line,1,1) = '1' and l_in_transaction = false) 
    then 
     parse_file_header(l_line); 
    end if; 
    if(substr(l_line,1,1) = '5' and l_in_transaction = false) 
    then 
     parse_transaction_header(l_line); 
     l_in_transaction := true; 
    end if; 
    if(l_in_transaction = true) 
    then 
     parse_transaction_row(l_line); 
    end if; 
    if(substr(l_line,1,1) = '8' and l_in_transaction = true) 
    then 
     parse_transaction_trailer(l_line); 
     l_in_transaction := false; 
    end if; 
    if(substr(l_line,1,1) = '9' and l_in_transaction = false) 
    then 
     parse_file_trailer(l_line); 
    end if; 

    end loop; 
exception 
    when no_data_found 
    then 
    utl_file.fclose(l_file); 
end; 
+0

Justinに感謝します。しかし、論理が「6」を1つ以上持つ「5」をどのように説明していますか? – QuickDrawMcgraw

+0

@QuickDrawMcgraw - もし5があれば、 'l_in_transaction'がtrueに設定されます。ループが繰り返されるたびに、次の行が読み込まれ、8に遭遇するまで 'parse_transaction_row'に渡されます。すべてのトランザクションの詳細行が6で始まっていれば(あなたの要求はそれを言っていません)、' l_in_transaction'と最初の文字が6のときはいつでも 'parse_transaction_row'を呼び出すことができます。 –

+0

私は元の質問の '5'ごとに '6'レコードを言及していなかったと思います。あなたのガイドに従って、それがどうなるかを見てください。ありがとう、ジャスティン、本当にありがとう。しかし、はい、1つ以上の '6が存在するためには、5つが必要です。 – QuickDrawMcgraw