PostgreSQL
 sql >> Database >  >> RDS >> PostgreSQL

È possibile utilizzare INSERT [...] ON CONFLICT per violazioni di chiavi esterne?

Sì, unisci le righe di input alla tabella di riferimento, rimuovendo così le righe senza corrispondenza nella colonna FK:

INSERT INTO entries(entry_id, referenced_id, name)
SELECT val.entry_id, val.referenced_id, val.name
FROM  (
  VALUES (1, 2, 'references two')
         -- more?
  ) val (entry_id, referenced_id, name)
JOIN   referenced USING (referenced_id)  -- drop rows without matching FK
ON     CONFLICT (entry_id) DO NOTHING;   -- drop rows with duplicate id

L'UPSERT stesso (INSERT ... ON CONFLICT DO NOTHING ) reagisce solo a violazioni uniche. Il manuale:

ON CONFLICT può essere utilizzato per specificare un'azione alternativa alla generazione di un vincolo univoco o di un errore di violazione del vincolo di esclusione. (Vedere la clausola SUL CONFLITTO di seguito.)

Dal momento che i VALUES l'espressione ora non è collegata a un INSERT direttamente, i tipi di colonna non vengono derivati ​​dalla tabella di destinazione. Potrebbe essere necessario trasmettere valori di input in modo esplicito quando si opera con tipi non di base. Vedi:

  • Trasmissione del tipo NULL durante l'aggiornamento di più righe