tutorial sirve que para postgresql

sirve - postgresql vs mysql



Insertar si no existe, de lo contrario, devolver id en postgresql (3)

Tengo una tabla simple en PostgreSQL que tiene tres columnas:

  • clave principal serial de identificación
  • clave varchar
  • valor varchar

Ya he visto esta pregunta aquí en SO: Insert, en la actualización duplicada en PostgreSQL? pero me pregunto cómo obtener la identificación si existe, en lugar de actualizar. Si la práctica estándar es siempre "insertar" o "actualizar si existe", ¿por qué? ¿El costo de hacer un SELECCIONAR (LÍMITE 1) es mayor que hacer una ACTUALIZACIÓN?

Tengo el siguiente código

INSERT INTO tag ("key", "value") SELECT ''key1'', ''value1'' WHERE NOT EXISTS ( SELECT id,"key","value" FROM tag WHERE key = ''key1'' AND value = ''value1'' );

que funciona en el sentido de que no se inserta si existe, pero me gustaría obtener la identificación. ¿Existe una cláusula de "RETORNO de identificación" o algo similar que pueda tocar ahí?


Sí, está returning

INSERT INTO tag ("key", "value") SELECT ''key1'', ''value1'' WHERE NOT EXISTS ( SELECT id, "key", "value" FROM node_tag WHERE key = ''key1'' AND value = ''value1'' ) returning id, "key", "value"

Para devolver la fila si ya existe

with s as ( select id, "key", "value" from tag where key = ''key1'' and value = ''value1'' ), i as ( insert into tag ("key", "value") select ''key1'', ''value1'' where not exists (select 1 from s) returning id, "key", "value" ) select id, "key", "value" from i union all select id, "key", "value" from s

Si la fila no existe, devolverá el insertado más el existente.

Por cierto, si el par "clave" / "valor" lo hace único, entonces es la clave principal, y no hay necesidad de una columna de identificación. A menos que uno o ambos pares de "clave" / "valor" puedan ser nulos.


Y puede almacenar el valor devuelto a las variables en forma de ... DEVOLVER campo1, campo2, ... EN var1, var2, ...

DEVOLVER devolverá normalmente una consulta que devolverá Error ''la consulta no tiene destino para los datos de resultado'' si la llama en plpgsql sin usar su conjunto de resultados devuelto.


with vals as ( select ''key5'' as key, ''value2'' as value ) insert into Test1 (key, value) select v.key, v.value from vals as v where not exists (select * from Test1 as t where t.key = v.key and t.value = v.value) returning id

demostración fiddle sql