Oracle
 sql >> Baza danych >  >> RDS >> Oracle

Oracle SQL-Loader skutecznie obsługuje wewnętrzne podwójne cytaty w wartościach

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.




  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Kontrola DB zbliża się do śmierci

  2. Jaki jest efekt umieszczenia zatwierdzenia po DML w procedurze?

  3. ORA-00904:Dobry Ośrodek:nieprawidłowy identyfikator

  4. Jak odzyskać lub zmienić hasło Oracle sysdba

  5. Jak określić język (angielski, chiński...) danego ciągu znaków w Oracle?