sql >> Databáze >  >> RDS >> Oracle

Oracle SQL-Loader efektivně zpracovává interní dvojité uvozovky v hodnotách

Pokud jste nikdy neměli roury v uzavřených polích, můžete to udělat z řídicího souboru. Pokud můžete mít v poli svislé i dvojité uvozovky, pak si myslím, že nemáte jinou možnost, než soubory předzpracovat, bohužel.

Vaše řešení [1], nahradit dvojité uvozovky s operátorem SQL , děje se příliš pozdě na to, aby bylo užitečné; oddělovače a uzávěry již byly interpretovány SQL*Loaderem před provedením kroku SQL. Vaše řešení [2], ignorování přílohy, by fungovalo v kombinaci s [1] - dokud jedno z polí neobsahovalo znak svislé čáry. A řešení [3] má stejné problémy jako použití [1] a/nebo [2] globálně.

Dokumentace pro určení oddělovačů zmiňuje, že:

Jinými slovy, pokud jste zopakovali dvojité uvozovky uvnitř pole pak budou escapována a objeví se v datech tabulky. Protože nemůžete ovládat generování dat, můžete soubory, které získáte, předběžně zpracovat a nahradit všechny dvojité uvozovky dvojitými uvozovkami. Kromě toho, že nechcete nahradit vše z nich – ty, které jsou ve skutečnosti skutečnými ohradami, by neměly uniknout.

Můžete použít regulární výraz k cílení na relevantní znaky, které vynechají ostatní. Není to moje silná oblast, ale myslím si, že to dokážete pomocí tvrzení o nahlédnutí a pohledu na pozadí .

Pokud jste měli soubor s názvem orig.txt obsahující:

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

můžete udělat:

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

To hledá dvojitou uvozovku, které nepředchází kotva na začátku řádku nebo svislý znak; a není následován znakem potrubí nebo kotvou konce řádku; a nahradí pouze ty s dvojitými uvozovkami. Což by vytvořilo new.txt obsahovat:

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

Dvojité uvozovky na začátku a konci polí nejsou upraveny, ale ty uprostřed jsou nyní vynechány. Pokud jste to potom načetli s kontrolním souborem s dvojitými uvozovkami:

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

Pak byste skončili s:

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"        

které, jak doufáme, odpovídají vašim původním datům. Mohou existovat okrajové případy, které nefungují (například dvojitá uvozovka následovaná svislou čarou uvnitř pole), ale existuje omezení toho, co můžete udělat, abyste se pokusili interpretovat data někoho jiného... Samozřejmě mohou existovat také (mnohem) lepší vzory regulárních výrazů.

Můžete také zvážit použití externí tabulky místo SQL*Loader, pokud je datový soubor (nebo může být) v adresáři Oracle a máte správná oprávnění. Stále musíte upravit soubor, ale můžete to udělat automaticky pomocí preprocessor direktivu namísto toho, abyste to museli udělat explicitně před voláním SQL*Loader.




  1. Osvědčené postupy:Úlohy údržby a vylepšení pro Oracle Cloud

  2. Zabránit uživatelům mít stejné uživatelské jméno

  3. Výběr části pole s regulárním výrazem

  4. Jak stáhnout soubor uložený v SQL DB v binárním formátu