Usar un cursor para update simultaneo

Tengo dos tablas "x" y "z" y quiero hacer un update de la tabla por a la z pero de varios registros, esto cuando las llaves principales sean iguales en ambas tablas... Pero no he podido hacer el script... Me manda un error y no lo he encontrado, este es el código... Si alguien pudieras ayudarme te lo agradecería...
Declare
CURSOR compu IS
SELECT tme_object_label,SUBSTR(fecha_capitalizacion,8,4),
valor_neto_inicial
FROM compu_costo;
dat_cve compu_costo.tme_object_laber%TYPE;
dat_fec compu_costo.fecha_capitalizacion%TYPE;
dat_cost compu_costo.valor_neto_inicial%TYPE;
BEGIN
OPEN compu;
LOOP
FETCH compu INTO dat_cve;
FETCH compu INTO dat_fec;
FETCH compu INTO dat_cost;
UPDATE ticomputadora
SET anio_adqui := dat_fec;
costo_adq := dat_costo
WHERE cve_compu = dat_cve;
END LOOP;
CLOSE compu;
END;

2 Respuestas

Respuesta
1
Me he dado cuenta de dos errores. El primero es que en el select del cursor vas a recuperar los valores de tres columnas pero solo asignas a una variable en lugar de tres. Es decir:
Si aparece en el cursor esto: SELECT A,B,C FROM T; debes recuperar los valores de esta forma: FETCH CUSOR_X INTO V_A, V_B, V_C; ¿OK?
Otra cosa es que haces un select de SUBSTR(fecha_capitalizacion, 8,4), que no sé que es lo que quieres obtener pero supongo que lo que querrás recuperar es el año de la fecha, para eso es mejor hacer TRUNCATE (fecha_capitalizacion,'YYYY') que te devuelve el año de la fecha. Y otra cosa es que entonces la variable sobre la que quieres recuperar el valor no debería ser del tipo compu_costo. Fecha_capitalizacion%TYPE sino del tipo NUMBER.
Respuesta
1
El problema del código es simple: declaras el cursor, este te devolverá n filas de tres columnas. Eso es importante, porque al hacer el FETCH no puedes asignar el resultado de una fila del conjunto activo devuelto por el cursor a una variable de tipo simple, sino a una variable compuesta, o sea, un RECORD que tenga tal vez esos tres mismos campos, y lo más importante, en ese orden y con ese mismo tipo de datos. Entonces, la instrucción quedaría de la siguiente manera:
Si asumimos que el record lo llamaremos compu_rec entonces:
--Declara tipo de dato compuesto
TYPE compu_rec_type IS RECORD
(dat_cve compu_costo.tme_object_laber%type,
compu_costo.fecha_capitalizacion%type,
compu_costo.valor_neto_inicial%type);
-- declaras variable de ese tipo de dato
compu_rec compu_rec_type;
--haces el FETCH
FETCH compu INTO compu_rec;
Entonces sí será directa la transferencia de datos entre el conjujto activo devuelto por el cursor y la variable PL/SQL local del subprograma.
Otro detalle:
UPDATE es una instrucción SQL, de tipo DML, o sea, no es PL/SQL lo que implica que el operador asignación (:=) no se usa en ella. ENtonces, la sentencia quedaría:
UPDATE ticomputadora
SET anio_adqui = dat_fec,
costo_adq = dat_costo
WHERE cve_compu = dat_cve;
Y visto lo anteriormente explicado, la perfecta sería:
UPDATE ticomputadora
SET anio_adqui = compu_rec.dat_fec,
costo_adq = compu_rec.dat_costo
WHERE cve_compu = compu_recdat_cve;
Ojalá estos datos puedan ayudarte a resolver el problema. Un placer.

Añade tu respuesta

Haz clic para o

Más respuestas relacionadas