Buenos días, listeros.
Recientemente he descubierto el maravilloso comando MERGE. Para comandos simples funciona pero ¿cuál sería la sintaxis correcta si lo quiero usar en un PL/SQL usando datos de un cursor?
Me explico, a la antigua usanza tengo un PL/SQL tan simple como el siguiente donde con el procedimiento hacercommit controlo el commit mediante un contador para no pasarme con el rollback (en el ejemplo tiene un valor absurdo de 10, pero es de pruebas) :
DECLARE
-- Cursor para Codigos de conceptos cargados por Loader en tabla auxiliar
CURSOR cur_tconceptos
IS
SELECT cod_tconcepto, descripcion1, descripcion2, descripcion3, orden
FROM tconceptos_aux;
-- Declaracion de variables
contador NUMBER;
caderror VARCHAR2 (200);
-- Procedimiento para realizar commit cada x operaciones en la BD.
PROCEDURE hacercommit
IS
BEGIN
contador := contador + 1;
IF (contador = 10)
THEN
COMMIT;
contador := 0;
END IF;
END hacercommit;
-- Fin Procedimiento para realizar commit cada x operaciones en la BD.
BEGIN
contador := 0;
caderror := NULL;
DBMS_OUTPUT.put_line
('====================================================================================='
);
DBMS_OUTPUT.put_line
( CHR (10)
|| 'Iniciando Proceso de actualización de TCONCEPTOS ('
|| TO_CHAR (SYSDATE, 'dd-mm-yyyy hh24:mi:ss')
|| ')...'
);
-- Tratamiento de los Codigos de conceptos.
FOR reg IN cur_tconceptos
LOOP
BEGIN
UPDATE tconceptos
SET descripcion1 = reg.descripcion1,
descripcion3 = reg.descripcion3,
descripcion2 = reg.descripcion2
WHERE cod_tconcepto = reg.cod_tconcepto;
IF SQL%NOTFOUND
THEN
INSERT INTO tconceptos
(cod_tconcepto, descripcion1,
descripcion2, descripcion3, orden
)
VALUES (reg.cod_tconcepto, reg.descripcion1,
reg.descripcion2, reg.descripcion3, reg.orden
);
DBMS_OUTPUT.put_line
( 'Se ha insertado un nuevo registro con código '
|| reg.cod_tconcepto
);
ELSE
DBMS_OUTPUT.put_line
( 'Se ha actualizado el registro con código '
|| reg.cod_tconcepto
);
END IF;
END;
hacercommit ();
END LOOP;
DBMS_OUTPUT.put_line
( CHR (10)
|| 'Terminado Proceso de actualización de TCONCEPTOS('
|| TO_CHAR (SYSDATE, 'dd-mm-yyyy hh24:mi:ss')
|| ')...'
);
DBMS_OUTPUT.put_line
('====================================================================================='
);
EXCEPTION
WHEN OTHERS
THEN
caderror :=
'Error al actualizar/insertar registros ' || RPAD (SQLERRM, 200);
DBMS_OUTPUT.put_line (caderror);
END;
/
Pues bien, lo que quisiera es reducir código, evitar toda la parte de
UPDATE....
IF SQL%NOTFOUND THEN INSERT....
Poniendo en su lugar algo parecido a
MERGE INTO tconceptos a
USING tconceptos_aux b
ON (a.cod_tconcepto = b.cod_tconcepto)
WHEN MATCHED THEN
UPDATE
SET a.descripcion1 = b.descripcion1, a.descripcion3 = b.descripcion3,
a.descripcion2 = b.descripcion2
WHEN NOT MATCHED THEN
INSERT
VALUES (b.cod_tconcepto, b.descripcion1, b.descripcion2, b.descripcion3,
b.orden);
Pero que me use el cursor cur_tconceptos de modo que la condición se transformara en algo como
ON (a.cod_tconcepto = reg.cod_tconcepto)
He buscado por ahí y no veo ningún ejemplo... ni siquiera sé si es factible.. pero ¿alguién sabe si se puede y cómo sería adaptado a mi ejemplo?
Muchas gracias y un saludete