sql >> Base de Datos >  >> RDS >> PostgreSQL

¿Se puede usar INSERT [...] ON CONFLICT para violaciones de clave externa?

Sí, una sus filas de entrada a la tabla a la que se hace referencia y, por lo tanto, elimine las filas que no coincidan en la columna 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

El UPSERT mismo (INSERT ... ON CONFLICT DO NOTHING ) solo reacciona ante infracciones únicas. El manual:

ON CONFLICT se puede utilizar para especificar una acción alternativa a generar una restricción única o un error de violación de la restricción de exclusión. (Consulte la Cláusula SOBRE CONFLICTO a continuación).

Dado que los VALUES expresión ahora no está adjunta a un INSERT directamente, los tipos de columna no se derivan de la tabla de destino. Es posible que debas transmitir valores de entrada explícitamente cuando se opera con tipos no básicos. Ver:

  • Conversión de tipo NULL al actualizar varias filas