囲まれたフィールドにパイプがない場合は、制御ファイルから行うことができます。フィールド内にパイプと二重引用符の両方を含めることができる場合は、残念ながらファイルを前処理する以外に選択肢はないと思います。
ソリューション[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を呼び出す前に明示的に行う必要はありません。