Hvis du kun indsætter en enkelt række ad gangen, kan du oprette en sparepunkt før indsættelsen og rulning til den, når indsættelsen mislykkes (eller frigiv den når indsættelsen lykkes).
For Postgres 9.5 eller nyere kan du bruge INSERT ... ON CONFLICT DO NOTHING
som gør hvad den siger. Du kan også skriv ON CONFLICT DO UPDATE SET column = value...
, som automagisk konverterer dit indstik til en opdatering af den række, du er i konflikt med (denne funktion kaldes nogle gange "upsert").
Dette virker ikke, fordi OP har at gøre med en fremmednøgle begrænsning i stedet for en unik begrænsning. I så fald kan du nemmest bruge savepoint-metoden, som jeg beskrev tidligere, men for flere rækker kan det vise sig at være trættende. Hvis du har brug for at indsætte flere rækker på én gang, bør det være rimeligt effektivt at opdele dem i flere insert-sætninger, forudsat du arbejder i autocommit-tilstand , alle indsættelser sker i én transaktion, og du indsætter ikke et meget stort antal rækker.
Nogle gange har du virkelig brug for flere inserts i en enkelt erklæring, fordi det rundtursomkostninger ved at tale med din database plus omkostningerne ved at have savepoints på hver insert simpelthen er for høje. I dette tilfælde er der en række ufuldkomne tilgange. Sandsynligvis den mindst dårlige er at bygge en indlejret forespørgsel, som udvælger dine data og forbinder dem med den anden tabel, noget som dette:
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;