sql - ¿Tiene DB2 una instrucción "insertar o actualizar"?
database insert-update (4)
Desde mi código (Java) deseo asegurarme de que exista una fila en la base de datos (DB2) después de que se ejecute mi código.
Mi código ahora select
y si no se devuelve ningún resultado, insert
. Realmente no me gusta este código ya que me expone a problemas de concurrencia cuando se ejecuta en un entorno de subprocesos múltiples.
Lo que me gustaría hacer es poner esta lógica en DB2 en lugar de en mi código Java. ¿Tiene DB2 una instrucción de insert-or-update
? ¿O algo así que pueda usar?
Por ejemplo:
insertupdate into mytable values (''myid'')
Otra forma de hacerlo sería hacer siempre la inserción y detectar "SQL-code -803 primary key already exists", pero me gustaría evitar eso si es posible.
Sí, DB2 tiene la instrucción MERGE, que hará un UPSERT (actualización o inserción).
MERGE INTO target_table USING source_table ON match-condition
{WHEN [NOT] MATCHED
THEN [UPDATE SET ...|DELETE|INSERT VALUES ....|SIGNAL ...]}
[ELSE IGNORE]
Ver:
Otra forma es ejecutar estas 2 consultas. Es más simple que crear una declaración MERGE:
update TABLE_NAME set FIELD_NAME=xxxxx where MyID=XXX;
INSERT INTO TABLE_NAME values (MyField1,MyField2)
WHERE NOT EXISTS(select 1 from TABLE_NAME where MyId=xxxx);
La primera consulta simplemente actualiza el campo que necesita, si existe MyId. El segundo inserta la fila en db si MyId no existe.
El resultado es que solo una de las consultas se ejecuta en su db.
Encontré este hilo porque realmente necesitaba una línea para DB2 INSERT O UPDATE.
La siguiente sintaxis parece funcionar, sin requerir una tabla temporal separada.
Funciona al usar VALUES () para crear una estructura de tabla. El SELECT * parece superávit en mi humilde opinión, pero sin él obtengo errores de sintaxis.
MERGE INTO mytable AS mt USING (
SELECT * FROM TABLE (
VALUES
(123, ''text'')
)
) AS vt(id, val) ON (mt.id = vt.id)
WHEN MATCHED THEN
UPDATE SET val = vt.val
WHEN NOT MATCHED THEN
INSERT (id, val) VALUES (vt.id, vt.val)
;
si tiene que insertar más de una fila, la parte VALUES se puede repetir sin tener que duplicar el resto.
VALUES
(123, ''text''),
(456, ''more'')
El resultado es una declaración única que puede INSERTAR O ACTUALIZAR una o varias filas, presumiblemente como una operación atómica.
Esta respuesta es, afortunadamente, para responder completamente a la consulta que MrSimpleMind tenía en uso-actualizar-e-insertar-en-misma-consulta y para proporcionar un ejemplo sencillo de trabajo de la sentencia MERGE de DB2 con un escenario de inserción y actualización de una vez (registro con La ID 2 se actualiza y la ID de registro 3 insertada).
CREATE TABLE STAGE.TEST_TAB ( ID INTEGER, DATE DATE, STATUS VARCHAR(10) );
COMMIT;
INSERT INTO TEST_TAB VALUES (1, ''2013-04-14'', NULL), (2, ''2013-04-15'', NULL); COMMIT;
MERGE INTO TEST_TAB T USING (
SELECT
3 NEW_ID,
CURRENT_DATE NEW_DATE,
''NEW'' NEW_STATUS
FROM
SYSIBM.DUAL
UNION ALL
SELECT
2 NEW_ID,
NULL NEW_DATE,
''OLD'' NEW_STATUS
FROM
SYSIBM.DUAL
) AS S
ON
S.NEW_ID = T.ID
WHEN MATCHED THEN
UPDATE SET
(T.STATUS) = (S.NEW_STATUS)
WHEN NOT MATCHED THEN
INSERT
(T.ID, T.DATE, T.STATUS) VALUES (S.NEW_ID, S.NEW_DATE, S.NEW_STATUS);
COMMIT;