PostgreSQL
 sql >> Base de données >  >> RDS >> PostgreSQL

Est-il possible d'attraper une violation de clé étrangère dans postgres

Si vous n'insérez qu'une seule ligne à la fois, vous pouvez créer un point de sauvegarde avant l'insertion et rollback lorsque l'insertion échoue (ou libérez-le lorsque l'insertion réussit).

Pour Postgres 9.5 ou version ultérieure, vous pouvez utiliser INSERT ... ON CONFLICT DO NOTHING qui fait ce qu'il dit. Vous pouvez aussi écrire ON CONFLICT DO UPDATE SET column = value... , qui convertira automatiquement votre insertion en une mise à jour de la ligne avec laquelle vous êtes en conflit (cette fonctionnalité est parfois appelée "upsert").

Cela ne fonctionne pas car OP traite une clé étrangère contrainte plutôt qu'un unique contrainte. Dans ce cas, vous pouvez plus facilement utiliser la méthode du point de sauvegarde que j'ai décrite précédemment, mais pour plusieurs lignes, cela peut s'avérer fastidieux. Si vous devez insérer plusieurs lignes à la fois, il devrait être raisonnablement performant de les diviser en plusieurs instructions d'insertion, à condition vous ne travaillez en mode autocommit , toutes les insertions se produisent en une seule transaction et vous n'insérez pas un très grand nombre de lignes.

Parfois, vous avez vraiment besoin de plusieurs insertions dans une seule instruction, car la surcharge aller-retour de la communication avec votre base de données, plus le coût des points de sauvegarde sur chaque insertion, est tout simplement trop élevée. Dans ce cas, il existe un certain nombre d'approches imparfaites. Probablement le moins mauvais consiste à créer une requête imbriquée qui sélectionne vos données et les joint à l'autre table, quelque chose comme ceci :

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;