2017-02-20 37 views
0

В этом заявлении SQLКак игнорировать строки, которые нарушают ограничение внешнего ключа в Postgres INSERT INTO?

INSERT INTO child (parentId, value) SELECT parentId, value FROM temptable 

child.parentId внешний ключ, ссылающийся на parent.id. Строки в таблице parent могут быть удалены в любое время, пока выполняется этот долговременный оператор INSERT INTO (который может вставить до нескольких миллионов строк).

Если child таблица не имеет соответствующего внешнего ключа в parentперед в INSERT INTO заявлении начинает работать, или если строка в parent таблице ссылочного из child был удален в то время как это INSERT INTO бежит, я бы хотел, INSERT INTO, чтобы молча игнорировать эту конкретную строку (и просто пропустить вставку в child строк, которые нарушают ограничение внешнего ключа), а не весь запрос.

Как это сделать? Я не знаком с тем, как в этом случае будут работать условия гонки.

ответ

2

Вы можете попытаться заблокировать ссылки строк таблицы parent в SELECT:

INSERT INTO child (parent_id, value) 
    SELECT t.parent_id, t.value 
    FROM temptable t 
    JOIN parent p ON t.parent_id = p.id 
    FOR UPDATE OF p; 

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

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

INSERT 
    ... 
    WHERE parent_id < 1000 

INSERT 
    ... 
    WHERE parent_id BETWEEN 1001 AND 2000 -- and so on. 

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

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