sql >> データベース >  >> RDS >> Oracle

OracleSQL-Loaderが値の内部二重引用符を効率的に処理する

    囲まれたフィールドにパイプがない場合は、制御ファイルから行うことができます。フィールド内にパイプと二重引用符の両方を含めることができる場合は、残念ながらファイルを前処理する以外に選択肢はないと思います。

    ソリューション[1]、二重引用符を置き換える SQL演算子を使用 、発生が遅すぎて役に立たない。区切り文字とエンクロージャーは、SQLステップを実行する前に、SQL*Loaderによってすでに解釈されています。エンクロージャーを無視するソリューション[2]は、フィールドの1つにパイプ文字が含まれるまで、[1]と組み合わせて機能します。また、ソリューション[3]には、[1]や[2]をグローバルに使用する場合と同じ問題があります。

    区切り文字の指定 のドキュメント 言及:

    つまり、内部の二重引用符を繰り返した場合 その後、フィールドはエスケープされ、テーブルデータに表示されます。データ生成を制御できないため、取得したファイルを前処理して、すべての二重引用符をエスケープされた二重引用符に置き換えることができます。 すべてを置き換えたくない場合を除きます それらのうち、実際には実際のエンクロージャーであるものはエスケープしないでください。

    正規表現を使用して、関連する文字をターゲットにすると、他の文字をスキップできます。私の得意分野ではありませんが、先読みと後読みのアサーション でこれを行うことができると思います。 。

    orig.txtというファイルがある場合 含む:

    "1"|A|"B"|"C|D"
    "2"|A|"B"|"C"D"
    3|A|""B""|"C|D"
    4|A|"B"|"C"D|E"F"G|H""
    

    あなたができること:

    perl -pe 's/(?<!^)(?<!\|)"(?!\|)(?!$)/""/g' orig.txt > new.txt
    

    これは、行開始アンカーまたはパイプ文字が前に付いていない二重引用符を探します。パイプ文字または行末アンカーが後に続きません。そして、それらだけをエスケープされた(二重引用符で囲まれた)二重引用符で置き換えます。 new.txtになります 含む:

    "1"|A|"B"|"C|D"
    "2"|A|"B"|"C""D"
    3|A|"""B"""|"C|D"
    4|A|"B"|"C""D|E""F""G|H"""
    

    フィールドの最初と最後の二重引用符は変更されませんが、中央の二重引用符はエスケープされます。次に、二重引用符で囲まれた制御ファイルをロードした場合:

    load data
    truncate
    into table t42
    fields terminated by '|' optionally enclosed by '"'
    (
      col1,
      col2,
      col3,
      col4
    )
    

    そうすると、次のようになります:

    select * from t42 order by col1;
    
          COL1 COL2       COL3       COL4                
    ---------- ---------- ---------- --------------------
             1 A          B          C|D                 
             2 A          B          C"D                 
             3 A          "B"        C|D                 
             3 A          B          C"D|E"F"G|H"        
    

    うまくいけば、元のデータと一致します。動作しないエッジケースがある場合があります(二重引用符の後にパイプが続く など) フィールド)ですが、他の人のデータを解釈しようとするためにできることには限界があります...もちろん、(はるかに)より良い正規表現パターンがあるかもしれません。

    外部テーブル> SQL * Loaderの代わりに、データファイルがOracleディレクトリにある(またはある可能性がある)場合で、適切な権限があります。ファイルを変更する必要がありますが、preprocessor SQL*Loaderを呼び出す前に明示的に行う必要はありません。




    1. これをTSQLからMYSQLに変換するにはどうすればよいですか?

    2. Psycopg / Postgres:接続がランダムにハングアウトする

    3. R12.2オンラインパッチ準備レポート

    4. トリガーがテーブルにある場合、OUTPUT句でUPDATEを使用することはできません