Игнорировать ошибки пакетной вставки Postgresql

Предположим, этот простой SQL-запрос:

INSERT INTO table (col1,col2) VALUES (val1,val2),(val3,val4),(val5,val6);

Допустим, val3 является недопустимым значением для col1. Это приведет к тому, что psql прервет всю команду INSERT — он не вставит ни (val1,val2), ни (val5,val6).

Можно ли заставить postgresql игнорировать эту ошибку, чтобы он не вставлял пару (val3,val4), но продолжал бы работать с (val1,val2) и (val5,val6)?

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

ERROR:  invalid byte sequence for encoding "UTF8": 0x00

... что делает целых 30000+ значений не вставленными в таблицу, потому что одно из этих значений неверно.


person grzaks    schedule 06.10.2010    source источник
comment
Кстати. Одним из решений, которое я придумал, является анализ этого текстового файла и изменение всех пакетных команд INSERT на несколько команд с одним значением. Но прежде чем я это реализую - может быть, вы, ребята, придумали лучшее решение.   -  person grzaks    schedule 06.10.2010
comment
Вам, вероятно, будет лучше использовать оператор COPY вместо большой вставки.   -  person Pointy    schedule 06.10.2010
comment
Кроме того, как эти файлы подготовлены? Почему там есть недопустимые последовательности байтов?   -  person Pointy    schedule 06.10.2010
comment
@Pointy: понятия не имею, почему. Они подготовлены другой компанией из их базы данных (я думаю, MySQL). Я не могу заставить их изменить формат дампа.   -  person grzaks    schedule 06.10.2010
comment
Что ж, вероятно, лучше всего было бы написать какой-нибудь простой фильтр для преобразования синтаксиса INSERT в файл CSV, а также для фильтрации фиктивных последовательностей UTF-8. Затем вы можете использовать COPY FROM, что в любом случае будет намного быстрее, чем набор операторов INSERT.   -  person Pointy    schedule 06.10.2010
comment
Верно. Это было бы даже лучше, чем переводить его на множество однострочных вставок. Я сделаю это, если никто не придумает лучшего решения.   -  person grzaks    schedule 06.10.2010


Ответы (1)


Приложение, которое обрабатывает входной файл, должно обернуть каждую инструкцию INSERT точкой сохранения. Если вставка не удалась, ее можно откатить до последней точки сохранения. Что-то типа:

(псевдокод)

foreach line
  set savepoint
  try 
    insert current line
  catch 
    rollback to savepoint
  end
endloop
commit
person a_horse_with_no_name    schedule 06.10.2010