Jeśli nigdy nie miałeś potoków w zamkniętych polach, możesz to zrobić z pliku kontrolnego. Jeśli w polu możesz umieścić zarówno potoki, jak i cudzysłowy, to myślę, że nie masz innego wyjścia, jak tylko wstępnie przetworzyć pliki.
Twoje rozwiązanie [1], aby zastąpić podwójne cudzysłowy z operatorem SQL , dzieje się za późno, aby było użyteczne; ograniczniki i załączniki zostały już zinterpretowane przez program SQL*Loader przed wykonaniem kroku SQL. Twoje rozwiązanie [2], aby zignorować załącznik, działałoby w połączeniu z [1] - dopóki jedno z pól nie będzie zawierało znaku kreski pionowej. Rozwiązanie [3] ma te same problemy, co używanie [1] i/lub [2] globalnie.
Dokumentacja określania ograniczników wspomina, że:
Innymi słowy, jeśli powtórzysz podwójne cudzysłowy wewnątrz pola, a następnie zostałyby zmienione i pojawiłyby się w danych tabeli. Ponieważ nie możesz kontrolować generowania danych, możesz wstępnie przetworzyć otrzymane pliki, aby zastąpić wszystkie podwójne cudzysłowy podwójnymi cudzysłowami. Tyle że nie chcesz zastąpić wszystkich z nich - te, które są w rzeczywistości prawdziwymi obudowami, nie powinny być omijane.
Możesz użyć wyrażenia regularnego, aby kierować odpowiednie znaki, pomijając inne. Nie moja mocna strona, ale myślę, że możesz to zrobić za pomocą aercji patrzących w przód i wstecz .
Gdybyś miał plik o nazwie orig.txt
zawierające:
"1"|A|"B"|"C|D"
"2"|A|"B"|"C"D"
3|A|""B""|"C|D"
4|A|"B"|"C"D|E"F"G|H""
możesz zrobić:
perl -pe 's/(?<!^)(?<!\|)"(?!\|)(?!$)/""/g' orig.txt > new.txt
To szuka podwójnego cudzysłowu, który nie jest poprzedzony kotwicą początku wiersza ani znakiem kreski pionowej; i nie następuje po nim znak kreski pionowej ani kotwica końca linii; i zastępuje tylko te cudzysłowami ze znakami ucieczki (podwojonymi). Co sprawiłoby, że new.txt
zawierać:
"1"|A|"B"|"C|D"
"2"|A|"B"|"C""D"
3|A|"""B"""|"C|D"
4|A|"B"|"C""D|E""F""G|H"""
Podwójne cudzysłowy na początku i na końcu pól nie są modyfikowane, ale te w środku są teraz pomijane. Jeśli następnie załadowałeś to za pomocą pliku kontrolnego z załącznikami w podwójnych cudzysłowach:
load data
truncate
into table t42
fields terminated by '|' optionally enclosed by '"'
(
col1,
col2,
col3,
col4
)
Wtedy skończysz z:
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"
który, miejmy nadzieję, pasuje do Twoich oryginalnych danych. Mogą wystąpić przypadki brzegowe, które nie działają (np. podwójny cudzysłów, po którym następuje pionowa kreska w pole), ale istnieje limit tego, co możesz zrobić, aby spróbować zinterpretować dane innej osoby... Oczywiście mogą istnieć również (znacznie) lepsze wzorce wyrażeń regularnych.
Możesz również rozważyć użycie tabeli zewnętrznej zamiast SQL*Loader, jeśli plik danych znajduje się (lub może znajdować się) w katalogu Oracle i masz odpowiednie uprawnienia. Nadal musisz zmodyfikować plik, ale możesz to zrobić automatycznie za pomocą preprocessor
dyrektywy, zamiast konieczności robienia tego wprost przed wywołaniem SQL*Loader.