11 Replies Latest reply: Jan 9, 2013 2:05 AM by okie1jp RSS

    SQLLDRでEOFの最終行をスキップしたい

    983414
      お世話になります。

      環境
       ORACLE11g

      SQLLDRでSJISのデータを取り込む際に最終行にEOFのみのレコードが存在し、除外したいのですが取り込まれてしまいます。
      WHEN句でNULLやEOFを指定できないですし、良い解決策が思いつきません。

      リファレンスを読んだのですが、先頭のN件をスキップする設定はありましたが、最終行をスキップする方法がわかりませんでした。
      よろしくお願いいたします。
        • 1. Re: SQLLDRでEOFの最終行をスキップしたい
          asahide
          NULLIFを設定できませんでしたっけ?
          いずれにせよ、今回の要件にはあわなそうですが。。

          ちなみにどのようなファイルでどのように取り込まれるのでしょうか。
          例えばで構いませんが、提示して頂けると判り易いかと思います。


          Oracle上ですぐには思い浮かびませんが、普通のファイル操作で削除してLOADする、という事は可能でしょうか。
          • 2. Re: SQLLDRでEOFの最終行をスキップしたい
            983414
            >NULLIFを設定できませんでしたっけ?
            いずれにせよ、今回の要件にはあわなそうですが。

            ちょっと見てみましたが各カラムに対して設定するのではなく、レコード自体を飛ばしたいのです。


            >ちなみにどのようなファイルでどのように取り込まれるのでしょうか。

            財務系のパッケージソフトから出力される固定長のデータです、編集などはできません。
            データ量は数十万~数百万、文字コードはS-JISのようです。
            この最終行に EOFがあります。


            >Oracle上ですぐには思い浮かびませんが、普通のファイル操作で削除してLOADする、という事は可能でしょうか。

            運用上厳しいです。
            • 3. Re: SQLLDRでEOFの最終行をスキップしたい
              asahide
              EOFって0x1aですよね?

              例えば0x1aをbadfile行きにするような制限をテーブル側にかけておくとかは可能でしょうか。
              • 4. Re: SQLLDRでEOFの最終行をスキップしたい
                weyk
                結局のところ、以下のような感じになっているということですか?
                ----------
                XXXXXXXXXXXXXXXXXXXXX[CR][LF]
                YYYYYYYYYYYYYYYYYYY[CR][LF]
                [EOF]
                -----------

                もしくは、固定長ファイルということで、LFやCRLFもない以下のような感じでしょうか?
                -----------
                XXXXXXXXXXXXXXXXXXXXXYYYYYYYYYYYYYYYYYYY[EOF]
                -----------
                (ここでの[EOF]は、データの終わりの意味のマーカーではなく、EOFの文字コードを持つ文字そのものの意)

                最初のケースで、[EOF]の1文字のみの行が問題であるなら、

                when (1)<>X'1A'

                と、POSITION指定で、16進数でEOFの文字コードを指定するといかがでしょうか。
                (「EOFを指定できない」というのは、この方法がだめだった という意味でしょうか?)

                もう少し、現状がどうなのか説明がほしい感じがします。
                • 5. Re: SQLLDRでEOFの最終行をスキップしたい
                  983414
                  失礼しました。
                  前述の

                  XXXXXXXXXXXXXXXXXXXXX[CR][LF]
                  YYYYYYYYYYYYYYYYYYY[CR][LF]
                  [EOF]

                  のイメージです。
                  最終行はバイナリエディタでみると「1A」になっております。



                  >最初のケースで、[EOF]の1文字のみの行が問題であるなら、
                  >when (1)<>X'1A'

                  実行したところ下記のエラーになりました。
                  ========================================
                  SQL*Loader-350: 行4に構文エラーがあります。
                  英数字以外の無効な文字列があります
                  WHEN (1) <> X'1A'
                  ========================================
                  • 6. Re: SQLLDRでEOFの最終行をスキップしたい
                    983414
                    >EOFって0x1aですよね?

                    そうです、バイナリディタで「1A」でした。



                    >例えば0x1aをbadfile行きにするような制限をテーブル側にかけておくとかは可能でしょうか。

                    ちょっとわからないですが、あまりイレギュラーなことは運用上厳しいです。
                    • 7. Re: SQLLDRでEOFの最終行をスキップしたい
                      okie1jp
                      実行したところ下記のエラーになりました。
                      ========================================
                      SQL*Loader-350: 行4に構文エラーがあります。
                      英数字以外の無効な文字列があります
                      WHEN (1) <> X'1A'
                      ========================================
                       まさかとは思いますが、これは、単純に不等号が全角文字(ダブルバイト)になっているからじゃないですか?
                      • 8. Re: SQLLDRでEOFの最終行をスキップしたい
                        Blueloco
                        EOFって、ファイルに存在するわけじゃない…って思っていましたが、COPYコマンド等に
                        よってファイルに書き込まれてしまう、というMS-DOSからの仕様なのだそうです。
                        Windows7では改善(?)されたようで、EOFは追加されませんでした。
                        実行したところ下記のエラーになりました。
                        ========================================
                        SQL*Loader-350: 行4に構文エラーがあります。
                        英数字以外の無効な文字列があります
                        WHEN (1) <> X'1A'
                        ========================================
                        WHEN句を入れている場所が違うのでは?
                        こちらで試したら、ちゃんとはじいてくれましたよ。


                        制御ファイル)
                        LOAD DATA
                        INFILE 'emp2.dat'
                        INTO TABLE emp2
                        WHEN (1) <> X'1A'
                        (ENAME POSITION(1:8) CHAR)
                        データファイル)
                        Apple   
                        Bird    
                        Car     
                        ^Z
                        結果)
                          3行のロードに成功しました。
                          0行はデータ・エラーのためロードされませんでした。
                          1行はWHEN句のエラーのためロードされませんでした。
                          0行はすべてのフィールドがNULLのためロードされませんでした。
                        
                        
                        SQL> select count(*) from emp2;
                        
                          COUNT(*)
                        ----------
                                 3
                        • 9. Re: SQLLDRでEOFの最終行をスキップしたい
                          983414
                          >まさかとは思いますが、これは、単純に不等号が全角文字(ダブルバイト)になっているからじゃないですか?

                          半角ですよ。


                          >WHEN句を入れている場所が違うのでは?

                          WHEN (1) <> ' ' のように記述するときちんと動作するので考えにくいです。


                          **************************
                          LOAD DATA
                          TRUNCATE
                          INTO TABLE TMP_TABLE
                          WHEN (1) X'1A'
                          TRAILING NULLCOLS(
                          **************************
                          上記の様に記載して実行したところ

                          **************************
                          SQL*Loader-350: 行4に構文エラーがあります。
                          =または"<>"ではなくキーワードが見つかりました。
                          WHEN (1) X'1A'
                          **************************
                          となりました。
                          そもそも=、<>を記載せずに動いているように見受けられますが、何か設定を変えられています?
                          • 10. Re: SQLLDRでEOFの最終行をスキップしたい
                            983414
                            【訂正】
                            すいません。
                            okie1jpさんのご指摘通り、全角だったのではないかと思われます。
                            大変失礼致しました。


                            WHEN (1) <> X'1A'
                            で動作致しました。
                            (<>は半角。全角にしないと当サイトで表示されないので、サンプルを全角にしていただいたのをそのまま使ってしまったために気づかなかったようです)

                            ご協力ありがとうございました。
                            • 11. Re: SQLLDRでEOFの最終行をスキップしたい
                              okie1jp
                               まぁ、この掲示板システムの余計なお世話機能(欠点)ですよね。
                               行端が括弧の場合、セミコロンを入れると顔文字に化けたりしますから…。