sql >> Database >  >> RDS >> PostgreSQL

Is het mogelijk om een ​​schending van een buitenlandse sleutel in postgres op te vangen?

Als u slechts één rij tegelijk invoegt, kunt u een opslaanpunt voor het invoegen en terugdraaien toe wanneer het invoegen mislukt (of laat het los wanneer het invoegen lukt).

Voor Postgres 9.5 of hoger kunt u INSERT ... ON CONFLICT DO NOTHING die doet wat het zegt. U kunt ook schrijf ON CONFLICT DO UPDATE SET column = value... , die uw invoeging automatisch omzet in een update van de rij waarmee u een conflict hebt (deze functionaliteit wordt soms "upsert" genoemd).

Dit werkt niet omdat OP te maken heeft met een buitenlandse sleutel beperking in plaats van een uniek beperking. In dat geval kunt u het gemakkelijkst de savepoint-methode gebruiken die ik eerder heb beschreven, maar voor meerdere rijen kan het vervelend zijn. Als u meerdere rijen tegelijk moet invoegen, zou het redelijk efficiënt moeten zijn om ze op te splitsen in meerdere invoeginstructies, op voorwaarde dat u werkt niet in de autocommit-modus , alle invoegingen vinden plaats in één transactie en u voegt niet een heel groot aantal rijen in.

Soms heb je echt meerdere inserts in één statement nodig, omdat de overhead van het praten met je database plus de kosten van het hebben van savepoints op elke insert gewoon te hoog is. In dit geval zijn er een aantal onvolmaakte benaderingen. Waarschijnlijk de minst slechte is het bouwen van een geneste query die uw gegevens selecteert en deze samenvoegt met de andere tabel, ongeveer als volgt:

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;



  1. MappingException Edm.String niet compatibel met SqlServer.varbinary

  2. PHPUnit-testen FOUT ALLEEN bij het bezoeken van de hoofdpagina ( visit ('/') ) in Laravel 5

  3. LAGER LIKE vs iLIKE

  4. MySQL-fout - U heeft een fout in uw SQL-syntaxis