Я выполняю вставку следующим образом:
INSERT INTO foo (a,b,c)
SELECT x,y,z
FROM fubar
WHERE ...
Однако, если некоторые строки, которые вставляются, нарушают дублирующийся ключевой индекс на нечто, я хочу, чтобы база данных проигнорировала те строки, и не вставила их и продолжила вставлять другие строки.
Рассматриваемый DB является Informix 11.5. В настоящее время все, что происходит, - то, что DB выдает исключение. Если я пытаюсь обработать исключение с:
ON EXCEPTION IN (-239)
END EXCEPTION WITH RESUME;
... это не помогает, потому что после того, как исключение поймано, вся вставка пропускается.
Я не думаю, что поддержки informix ВСТАВЛЯЮТ, ИГНОРИРУЮТ или ВСТАВЛЯЮТ... НА ДЕЛАЮТ ДУБЛИКАТ КЛЮЧА..., но не стесняются исправлять меня, если я неправ.
Используйте, если оператор и существует функция для проверки существующих записей. Или вы, вероятно, могут включать в себя функцию, существующую в пункте, где ниже
INSERT INTO foo (a,b,c)
SELECT x,y,z
FROM fubar
WHERE (NOT EXISTS(SELECT a FROM foo WHERE ...))
Я не знаю об Informix, но с SQL Server вы можете создать индекс, сделать его уникальным, а затем установить свойство, чтобы он игнорирул дублирующиеся клавиши, чтобы никакой ошибку не бросается на дубликат. Это просто игнорируется. Возможно, Informix имеет что-то подобное.
В зависимости от того, хотите ли вы знать все обо всех ошибках (обычно в результате операции загрузки данных), рассмотрите возможность использования таблиц нарушений .
START VIOLATIONS TABLE FOR foo;
Это создаст пару таблиц foo_vio и foo_dia, которые будут содержать информацию о строках, которые нарушают ограничения целостности в таблице.
Когда у вас будет достаточно, вы используете:
STOP VIOLATIONS TABLE FOR foo;
Вы можете очистить диагностические таблицы на досуге. В команде есть навороты для управления тем, какая таблица используется и т. Д. (Я, возможно, должен отметить, что это предполагает, что вы используете IDS (IBM Informix Dynamic Server), а не, скажем, Informix SE или Informix OnLine.)
Таблицы нарушений - это вариант для тяжелых условий эксплуатации - подходят для нагрузок и т.п. Обычно они не используются для защиты обычного SQL. Для этого достаточно эффективен защищенный INSERT (с SELECT и WHERE NOT EXISTS) - он требует, чтобы данные уже были в таблице, но временные таблицы легко создавать.
Есть еще пара вариантов для рассмотрения.
Начиная с версии 11.50, Informix поддерживает утверждение MERGE. Это может быть использовано для вставки строк из fubar, где соответствующая строка в foo не существует, и для обновления строк в foo значениями из fubar, где соответствующая строка уже существует в foo (проблема дублирующего ключа).
Другой способ взглянуть на это:
SELECT fubar.*
FROM fubar JOIN foo ON fubar.pk = foo.pk
INTO TEMP duplicate_entries;
DELETE FROM fubar WHERE pk IN (SELECT pk FROM duplicate_entries);
INSERT INTO foo SELECT * FROM fubar;
...processs duplicate_entries
DROP TABLE duplicate_entries
Это очищает исходную таблицу (fubar) от дубликатов записей (предполагая, что дублируется только первичный ключ) перед попыткой вставить данные. Таблица duplicate_entries содержит строки в fubar с ключами-дубликатами - те, которые требуют специальной обработки в той или иной форме. Или вы можете просто удалить и проигнорировать эти строки, хотя, по моему опыту, это редко бывает хорошей идеей.