игнорировать вставку строк, которые нарушают индекс дубликата ключа - PullRequest
6 голосов
/ 01 февраля 2010

Я выполняю вставку следующим образом:

INSERT INTO foo (a,b,c)
   SELECT x,y,z
   FROM fubar
   WHERE ...

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

БД, о которой идет речь, - это Informix 11.5. В настоящее время все, что происходит, это то, что БД выдает исключение. Если я попытаюсь обработать исключение с помощью:

ON EXCEPTION IN (-239)
END EXCEPTION WITH RESUME;

... это не помогает, потому что после того, как исключение поймано, вся вставка пропускается.

Я не думаю, что informix поддерживает INSERT IGNORE или INSERT ... ON DUPLICATE KEY ..., но не стесняйтесь исправлять меня, если я ошибаюсь.

Ответы [ 5 ]

5 голосов
/ 01 февраля 2010

Используйте оператор IF и функцию EXISTS для проверки существующих записей. Или, возможно, вы можете включить эту функцию EXISTS в предложение WHERE, как показано ниже

INSERT INTO foo (a,b,c) 
SELECT x,y,z 
FROM fubar 
WHERE (NOT EXISTS(SELECT a FROM foo WHERE ...))
3 голосов
/ 01 февраля 2010

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

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) достаточно эффективен - он требует, чтобы данные уже были в таблице, но временные таблицы легко создавать.

2 голосов
/ 09 ноября 2017

Сгруппируйте, может быть, ваш друг в этом. Для предотвращения ввода повторяющихся строк. Используйте группу по вашему выбору. Это заставит дубликаты в уникальный ряд. Единственное, что я хотел бы сделать, это проверить, нет ли проблем с производительностью. Кроме того, убедитесь, что вы включили в группу все строки, которые хотите быть уникальными, иначе вы можете исключить строки, которые не являются дубликатами.

INSERT INTO FOO(Name, Address, Age, Gadget, Price)
select Name, Age, Gadget, Price
from foobar
group by Name, Age, Gadget, Price

Где Имя, Возраст, Гаджет, Цена образуют индекс первичного ключа (или индекс уникального ключа). Другая возможность - записать дублированные строки в таблицу ошибок без индекса, а затем разрешить дубликаты, прежде чем вставлять их в новую таблицу. Просто нужно добавить пункт, имеющий количество (*)> 1 к приведенному выше.

2 голосов
/ 02 февраля 2010

Есть еще несколько вариантов для рассмотрения.

Начиная с версии 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 с дублирующимися ключами - те, которые нуждаются в специальной обработке в той или иной форме. Или вы можете просто удалить и проигнорировать эти строки, хотя, по моему опыту, это редко хорошая идея.

0 голосов
/ 01 февраля 2010

Я не знаю об Informix, но с помощью SQL Server вы можете создать индекс, сделать его уникальным, а затем установить свойство, позволяющее игнорировать дубликаты ключей, чтобы при дублировании не возникало ошибок. Это просто игнорируется. Возможно, в Informix есть нечто подобное.

...