Ако вмъквате само един ред наведнъж, можете да създадете точка за запис преди вмъкването и връщане назад към него, когато вмъкването е неуспешно (или освободете го когато вмъкването е успешно).
За Postgres 9.5 или по-нова версия можете да използвате INSERT ... ON CONFLICT DO NOTHING
което прави това, което казва. Можете също напишете ON CONFLICT DO UPDATE SET column = value...
, което автоматично ще преобразува вашето вмъкване в актуализация на реда, с който сте в конфликт (тази функционалност понякога се нарича "upsert").
Това не работи, защото OP работи с чужд ключ ограничение, а не уникален ограничение. В такъв случай можете най-лесно да използвате метода на точка за запис, който описах по-рано, но за няколко реда може да се окаже досаден. Ако трябва да вмъкнете няколко реда наведнъж, би трябвало да е разумно ефективно да ги разделите на множество изрази за вмъкване, осигурени не работите в режим на автоматично предаване , всички вмъквания се извършват в една транзакция и не вмъквате много голям брой редове.
Понякога наистина се нуждаете от множество вмъквания в един оператор, тъй като режийните разходи за двупосочни разговори с вашата база данни плюс цената на наличието на точки за запис на всяко вмъкване са просто твърде високи. В този случай има редица несъвършени подходи. Вероятно най-малкото лошо е да създадете вложена заявка, която избира вашите данни и ги свързва с другата таблица, нещо като това:
INSERT INTO table_A (column_A, column_B, column_C)
SELECT A_rows.*
FROM VALUES (...) AS A_rows(column_A, column_B, column_C)
JOIN table_B ON A_rows.column_B = table_B.column_B;