2010-12-29 17 views
6

Así que estoy viniendo de MySQL en el que podía hacer INSERT on DUPLICATE UPDATE:sintaxis de MERGE utilizado para upsert o INSERTAR ACTUALIZACIÓN duplicado

INSERT INTO table (a,b,c) 
VALUES (1,2,3) 
ON DUPLICATE KEY UPDATE c=c+1; 

Pero ahora estoy usando PostgreSQL y hay esfuerzos para añadir la funcionalidad UPSERT, parece que MERGE podría funcionar para lo que me gustaría, pero quería ver si esta es la sintaxis más óptima. Example Syntax 1, I've also seen this but don't understand how to implement. No he intentado esto todavía porque pensé que MERGE se usó para fusionar datos de la tabla 1 a la tabla 2 o ¿algo así funcionaría?

MERGE 
INTO table 
USING table 
ON  c = 1 
WHEN MATCHED THEN 
UPDATE 
SET  c=c+1 
WHEN NOT MATCHED THEN 
INSERT (a,b,c) 
VALUES (1,2,3) 

¿Alguna otra sugerencia?

Respuesta

13

Hasta MERGE está disponible, utilizar este enfoque sólido: Insert, on duplicate update in PostgreSQL?

+0

¿En qué versión de Postgres es compatible? –

+0

MERGE está en Todo para 9.1 http://wiki.postgresql.org/wiki/Todo –

+0

hay una gema de rubí para esto: ['Upsert'] (https://github.com/seamusabshere/upsert) –

0
MERGE INTO table 
    USING (VALUES (1, 2, 3)) AS newvalues (a, b, c) 
    ON table.c = newvalues.c -- or whatever the PK is 
    WHEN MATCHED THEN UPDATE SET c = c + 1 
    WHEN NOT MATCHED THEN INSERT (a, b, c) 
           VALUES (newvalues.a, newvalues.b, newvalues.c) 

La clave aquí es que en lugar de combinar en otra tabla se crea una fuente constante de mesa utilizando la construcción VALUES en la cláusula USING. Las reglas de fusión exactas que puedes adaptar a gusto obviamente.

Véase también http://petereisentraut.blogspot.com/2010/05/merge-syntax.html.

+0

Pero esto no es (aún) con el apoyo de PostgreSQL, ¿verdad? –

+0

Hmm ¿esto todavía es compatible? –

+1

el parche está 'esperando al autor' - https://commitfest.postgresql.org/action/commitfest_view/inprogress –

0

Creo que "MERGE" aún no está en Postgres pero se supone que está en 9.1.

me gusta usar RULE s en lugar

CREATE OR REPLACE RULE "insert_ignore" 
AS ON INSERT TO "table" WHERE 
    NEW.id = OLD.id --whatever your conditions are 
DO INSTEAD NOTHING; 

Lo que se ha vinculado ("Insertar, en la actualización duplicado (PostgreSQL)") es básicamente algunos pgsql que usted alimenta a los datos. Creo que la RULE es más elegante ya que no es necesario que los llames explícitamente y funcionan de forma transparente en segundo plano sin la necesidad de llamar a un procedimiento dentro de tu INSERT real.

+0

¿Sería esto un INSERT else IGNORE/SKIP? –

+0

Es IGNORAR/PASE ya que comprueba la existencia y, de ser así, omita. Lo mismo funcionará para acciones de ACTUALIZACIÓN. Considere las REGLAS como "un tipo de desencadenante" que pueden modificar la consulta en sí reescribiéndola o (como en este caso) ignorando las partes (o todas) de ella. – DrColossos

+1

Hice esto pero OLD.id dio un error, no me gustó el valor. ¿Alguna idea? –

3

Hasta fusión se admite la forma más sencilla la OMI es simplemente dividirla en dos consultas:

BEGIN; 
    INSERT INTO t (a,b,c) VALUES (1,2,3) WHERE id != 1; 
    UPDATE t SET c=c+1 WHERE id = 1; 
END; 

donde id sería cambiado a la condición apropiada.

+0

hmm Me gusta este enfoque a pesar de que le está costando dos consultas –

+0

hmm, no funciona en las pruebas. me da un error en la condición DONDE –

Cuestiones relacionadas