2017-01-02 16 views
1

У меня есть проблемы с Oracle SQL Loader и поиск эффективного и простого решения. Мои исходные файлы, которые необходимо загрузить, - это номер |, где значения заключены в Double Quotes ". проблема заключается в том, что некоторые из значений содержат внутренние двойные кавычки.Oracle SQL-Loader эффективно управляет внутренними двойными котировками в значениях

например: ..."|"a":"b"|"...

это вызывает мои записи должны быть отвергнуты под предлогом:

no terminator found after TERMINATED and ENCLOSED field 

существуют различные решения, через Интернет, но не кажется, подходит:

[1] Я попытался заменить все внутренние двойные кавычки в кавычках, , но кажется, что при применении этой функции слишком много полей в файлах управления (I hav е ~ 2000 + поля и используя FILLER загружать только подмножество) загрузчик жалуется снова:

SQL*Loader-350: Syntax error at line 7. 
Expecting "," or ")", found ",". 
field1 char(36) "replace(:field1,'"','""')", 

(я не знаю, почему, но при применении этого решения на узком подмножестве столбцов это похоже на работу)

Дело в том, что потенциально все поля могут включать внутренние двойные кавычки.

[2] Я могу загрузить все данные при отсутствии глобального optionally enclosed by '"', но тогда все заключенные кавычки становятся частью данных в целевой таблице.

[3] можно опустить глобальное optionally enclosed by '"' заявления и поместить его только в выбранных полях, в то время как попытаться "replace(:field1,'"','""')" заявления на оставшемся, но это трудно осуществить, как я не могу знать заранее, какие подозреваемые поля для включения внутренних двойных кавычек.

вот мои вопросы:

  1. не существует простого способа убедить погрузчик для обработки с ухода за внутренними двойными кавычками (когда значения заключены в них)?

  2. Если я вынужден исправить данные ad-hock, есть ли одна команда Linux liner для преобразования только внутренних двойных кавычек в другую строку/char, говорят, одинарные кавычки?

  3. Если я вынужден загружать данные с помощью кавычек в целевую таблицу, существует ли простой способ удалить двойные кавычки из всех полей, все сразу (таблица имеет 1000 столбцов). является ли решение практической производительности разумным для очень больших таблиц?

+0

Может ли какое-либо из закрытых полей (которые могут содержать или не содержать двойные кавычки) содержать символ ограничителя - или действительно ли оболочка действительно избыточна? Может ли исходный файл генерироваться без вложений или с другим неиспользуемым символом? Удаление их перед обработкой может быть затруднительным (через регулярное выражение); ваш текущий 'replace()' слишком поздно, хотя после того, как запись была разделена на поля. Вы также можете посмотреть внешние таблицы с препроцессором для удаления корпусов. –

+0

в первом файле, в котором я разбиваюсь, в данных нет данных - я предполагаю, что это редкий символ в свободном тексте, но я не могу предположить, что он никогда не появится, я не могу контролировать файлы, а поля могут содержать бесплатно текст третьей стороны. Я понимаю, что мне, возможно, придется искать исправление входного файла - мне придется сделать это простым и эффективным способом. Я как бы надеялся, есть простое исправление для файла управления без обработки самой информации (за пределами загрузчика) – kamashay

ответ

2

Если у вас никогда не было труб в закрытых полях, вы можете сделать это из файла управления. Если вы можете иметь как трубы, так и двойные кавычки внутри поля, то, думаю, у вас нет выбора, кроме как предварительно обрабатывать файлы, к сожалению.

Ваше решение [1], чтобы заменить двойные кавычки with an SQL operator, происходит слишком поздно, чтобы быть полезным; разделители и вложения уже были интерпретированы SQL * Loader до того, как он выполнит шаг SQL. Ваше решение [2], чтобы игнорировать оболочку, будет работать в комбинации с [1] - пока одно из полей не будет содержать символ канала. И решение [3] имеет те же проблемы, что и использование [1] и/или [2] во всем мире.

Документация specifying delimiters упоминает, что:

Иногда знак препинания, который разделитель должен также быть включены в данные. Чтобы сделать это возможным, два смежных разделительных символа интерпретируются как одно вхождение символа, и этот символ включен в данные.

Другими словами, если вы повторили двойные кавычки внутри полей, то они будут уцелевших и появится в таблице данных. Поскольку вы не можете управлять генерацией данных, вы можете предварительно обработать файлы, которые вы получаете, чтобы заменить все двойные кавычки на экранированные двойные кавычки. За исключением того, что вы не хотите заменять все из них - те, которые на самом деле настоящие шкафы, не должны быть экранированы.

Вы можете использовать регулярное выражение для таргетинга соответствующих символов, которое пропускает другие. Не моя сильная область, но я думаю, вы можете сделать это с lookahead and lookbehind assertions.

Если у вас файл с именем 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"   

, который мы надеемся, совпадающим исходные данные. Там могут быть случаи краев, которые не работают (например, двойная кавычка, за которой следует ) в поле), но есть предел тому, что вы можете сделать, чтобы попытаться интерпретировать чужие данные ... Также может быть (много) лучшие шаблоны регулярных выражений, конечно.


Вы также могли бы рассмотреть возможность использования an external table вместо SQL * Loader, если файл данных (или может быть) в каталоге Oracle и у вас есть права доступа. Вам все равно придется модифицировать файл, но вы можете сделать это автоматически с помощью директивы preprocessor, вместо того, чтобы делать это явно перед вызовом SQL * Loader.

+0

отличный ответ! это действительно разъяснило мои варианты проблемы – kamashay

 Смежные вопросы

  • Нет связанных вопросов^_^