Oracle - ¿Por qué mi procedimiento almacenado elimina los datos?

   
Vista:

¿Por qué mi procedimiento almacenado elimina los datos?

Publicado por Lena (14 intervenciones) el 06/10/2015 01:06:25
¿Por qué mi procedimiento almacenado elimina los datos?

Estoy haciendo un procedimiento almacenado que elimine los números de un empleado dado de baja de una tabla que contiene un campo "S_valor", un ejemplo sería:
1,2,54,289,86,30,476,268,285,259,224,719,801 --el 30 y el 801 ya fueron dados de baja
Pero al ejecutarlo, en lugar de eliminar el 801 o el 30, me elimina todo el campo!

si cambio el commit de lugar, me manda "recuperación fuera de secuencia"

Agradezco cualquier pista

Anexo el código completo:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
CREATE OR REPLACE PROCEDURE SP_AFTER_ESTATUS_BAJA
--Este procedimiento almacenado elimina de la tabla aplicaciones a los empleados que ya fueron dados de baja
--(estatus 9 en c_personal)
 IS
 BEGIN
        dbms_output.enable;
        DBMS_OUTPUT.ENABLE(10000000);
 
        DECLARE
        CURSOR cur_TraeIdEmpleadoBaja
        IS
            SELECT n_id_personal
            FROM esquema.PERSONAL
            WHERE n_id_estatus = 9;
            ORDER BY 1 asc;
            v_baja cur_TraeIdEmpleadoBaja%rowtype;
 
        CURSOR cur_aplicaciones
        IS
            SELECT s_valor
            FROM esquema.aplicaciones
            WHERE REGEXP_LIKE(esquema.aplicaciones.s_valor,('^(' || v_baja.n_id_personal || '),|,(' || v_baja.n_id_personal || '),|,(' || v_baja.n_id_personal || ')$|^(' || v_baja.n_id_personal || ')$'))
            FOR UPDATE;
            s_valor aplicaciones.s_valor%TYPE;
            v_registro cur_aplicaciones%rowtype;
 
       BEGIN
          OPEN cur_TraeIdEmpleadoBaja;
                    LOOP
                        FETCH cur_TraeIdEmpleadoBaja INTO v_baja;
                        EXIT WHEN cur_TraeIdEmpleadoBaja%notfound;
                        dbms_output.put_line ('Id personal baja'|| v_baja.n_id_personal);
 
                        BEGIN --CUR APLICACIONES
                            OPEN cur_aplicaciones;
                                LOOP
                                UPDATE esquema.aplicaciones
                                SET s_valor = REGEXP_REPLACE (v_registro.s_valor,('^(' || v_baja.n_id_personal || '),|,(' || v_baja.n_id_personal || ')$|^(' || v_baja.n_id_personal || ')$'),'')
                                WHERE REGEXP_LIKE(v_registro.s_valor, ('^(' || v_baja.n_id_personal || '),|,(' || v_baja.n_id_personal || ')$|^(' || v_baja.n_id_personal || ')$'));
                                --Elimina el id que se encuentre al inicio del registro, al final del registro o que sea el único valor en el registro
                                 UPDATE esquema.aplicaciones
                                    SET s_valor = REGEXP_REPLACE (esquema.aplicaciones.s_valor, ',(' || v_registro.s_valor || '),',',')
                                    WHERE REGEXP_LIKE(esquema.aplicaciones.s_valor, ',(' || v_registro.s_valor || '),');
                                    --Elimina el id que se encuentre en el medio del registro, rodeado por comas   */ 
                                    FETCH cur_aplicaciones INTO v_registro;
                                EXIT WHEN cur_aplicaciones%notfound;
                                dbms_output.put_line (' Actualicé '|| v_registro.s_valor);
                                END LOOP; --aplicaciones
                            END cur_aplicaciones;
                        CLOSE cur_aplicaciones;
                        COMMIT;
                    END LOOP; --trae id empleado baja
           CLOSE cur_TraeIdEmpleadoBaja;
           END cur_TraeIdEmpleadoBaja;
 
 
 
       EXCEPTION
        WHEN OTHERS THEN
        DBMS_OUTPUT.put_line (SQLERRM);
      ROLLBACK;
 
END SP_AFTER_ESTATUS_BAJA;
/
Valora esta pregunta
Me gusta: Está pregunta es útil y esta claraNo me gusta: Está pregunta no esta clara o no es útil
0
Responder

¿Por qué mi procedimiento almacenado elimina los datos?

Publicado por Rafael (178 intervenciones) el 06/10/2015 12:28:59
Bueno pues asi de primeras...

Abres el curso cur_aplicaciones
Realizas los updates y luego haces el FETCH...

Pero el update lo realizas con los valores que se supone trae v_registro; que como no has hecho FETCH pues esta VACIO que te pone???
VACIO

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
BEGIN --CUR APLICACIONES
	OPEN cur_aplicaciones;
		LOOP
 
			FETCH cur_aplicaciones INTO v_registro;
		EXIT WHEN cur_aplicaciones%notfound;
 
		UPDATE esquema.aplicaciones
		SET s_valor = REGEXP_REPLACE (v_registro.s_valor,('^(' || v_baja.n_id_personal || '),|,(' || v_baja.n_id_personal || ')$|^(' || v_baja.n_id_personal || ')$'),'')
		WHERE REGEXP_LIKE(v_registro.s_valor, ('^(' || v_baja.n_id_personal || '),|,(' || v_baja.n_id_personal || ')$|^(' || v_baja.n_id_personal || ')$'));
 
		--Elimina el id que se encuentre al inicio del registro, al final del registro o que sea el único valor en el registro
			UPDATE esquema.aplicaciones
			SET s_valor = REGEXP_REPLACE (esquema.aplicaciones.s_valor, ',(' || v_registro.s_valor || '),',',')
			WHERE REGEXP_LIKE(esquema.aplicaciones.s_valor, ',(' || v_registro.s_valor || '),');
 
			--Elimina el id que se encuentre en el medio del registro, rodeado por comas   */ 
 
		dbms_output.put_line (' Actualicé '|| v_registro.s_valor);
 
		END LOOP; --aplicaciones
	END cur_aplicaciones;
CLOSE cur_aplicaciones;

Prueba asi...
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
1
Comentar

¿Por qué mi procedimiento almacenado elimina los datos?

Publicado por Lena (14 intervenciones) el 06/10/2015 19:47:42
Tienes razón Rafael, ahora ya actualiza, el problema que tengo ahora es que me pone en un campo, el contenido del que modificó.

Me explico: si tengo estos dos registros:
RptChurn 54,30,17,19,1,86,186,44,139,719,224,259
nIdsDestDashbVtasSpec 17,19,54,1,549,245,168,86,169,186,2,30,289,479,719,801,268

cuando elimina el 30, me deja ambos como

nIdsDestDashbTrafico 17,19,54,1,549,245,168,86,169,186,2,289,479,268
RptChurn 17,19,54,1,549,245,168,86,169,186,2,289,479,268

De hecho en toda la tabla me pone el mismo valor para ese registro.

El update que puse en un principio está mal, este es el "correcto":
1
2
3
4
5
6
7
8
9
UPDATE IJANEZ.tb_cfg_aplicaciones
      SET s_valor = REGEXP_REPLACE (v_registro.s_valor,('^(' || v_baja.n_id_personal || '),|,(' || v_baja.n_id_personal || ')$|^(' || v_baja.n_id_personal || ')$'),'')
      WHERE REGEXP_LIKE(v_registro.s_valor, ('^(' || v_baja.n_id_personal || '),|,(' || v_baja.n_id_personal || ')$|^(' || v_baja.n_id_personal || ')$'));*/ 
      --Elimina el id que se encuentre al inicio del registro, al final del registro o que sea el único valor en el registro
      UPDATE IJANEZ.tb_cfg_aplicaciones
      SET s_valor = REGEXP_REPLACE (v_registro.s_valor, ',(' || v_baja.n_id_personal || '),',',')
      WHERE REGEXP_LIKE(v_registro.s_valor, ',(' || v_baja.n_id_personal || '),');
 
      --Elimina el id que se encuentre en el medio del registro, rodeado por comas

Lo que intento decirle, es que busque id que trae del cursor TraeIdEmpleadoBaja en cada registro que trae el cursor de aplicaciones para que lo elimine ahi...

Si sustituyo los updates por select, me muestra cada registro que tiene un empleado dado de baja... ¿por qué no lo elimina?

Muchas gracias por tu apoyo
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar

¿Por qué mi procedimiento almacenado elimina los datos?

Publicado por Rafael (178 intervenciones) el 07/10/2015 08:31:17
Pues lo hace asi precisamente por que no le dices que solo actualice el ID si no que trata de modificarlo todo de nuevo...

Veamos este cursor se trae los valores pero no el id:
1
2
3
4
5
6
CURSOR cur_aplicaciones
        IS
            SELECT s_valor
            FROM esquema.aplicaciones
            WHERE REGEXP_LIKE(esquema.aplicaciones.s_valor,('^(' || v_baja.n_id_personal || '),|,(' || v_baja.n_id_personal || '),|,(' || v_baja.n_id_personal || ')$|^(' || v_baja.n_id_personal || ')$'))
            FOR UPDATE;

Si AQUI trajeras el ID de la tabla aplicaciones...
Su pongamos que el ID fuera n_id_aplicaciones

Al hacer el update tendrias que poner algo talque asi
1
2
3
4
5
6
7
8
UPDATE esquema.aplicaciones
		SET s_valor = REGEXP_REPLACE (v_registro.s_valor,('^(' || v_baja.n_id_personal || '),|,(' || v_baja.n_id_personal || ')$|^(' || v_baja.n_id_personal || ')$'),'')
		WHERE n_id_aplicaciones = v_registro.n_id_aplicaciones;
 
		--Elimina el id que se encuentre al inicio del registro, al final del registro o que sea el único valor en el registro
			UPDATE esquema.aplicaciones
			SET s_valor = REGEXP_REPLACE (esquema.aplicaciones.s_valor, ',(' || v_registro.s_valor || '),',',')
		        WHERE n_id_aplicaciones = v_registro.n_id_aplicaciones;

Me he explicado???

Saludos
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
1
Comentar

¿Por qué mi procedimiento almacenado elimina los datos?

Publicado por Lena (14 intervenciones) el 07/10/2015 18:48:12
Gracias Rafael por tu apoyo. Sí, si te explicas, la que no se explica bien soy yo xD. La tabla aplicaciones no tiene un ID con el cual pueda hacer match en la tabla de personal, precisamente ese es el motivo por el que utilizo la expresión regular para poder buscar ahi. Pongo un ejemplo de su estructura:

N_ID_APLICACION S_CLAVE S_VALOR S_DESCRIPCION
1 RptChurn 54,30,1,86,186,44,139,719,224,259 Reporte con cifras mensuales, clientes y usuarios para los servicios recurrentes

S_SUBJECT_NOM_REPORTE Reporte Churn

El Id de la aplicación no tiene nada que ver con el de la tabla personal, el id de la tabla de personal, sólo aparece en "S_VALOR" .

Hice la modificación pertinente que me comentaste y quedó así:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
BEGIN
          OPEN cur_TraeIdEmpleadoBaja;
                    LOOP
                        FETCH cur_TraeIdEmpleadoBaja INTO v_baja;
                        EXIT WHEN cur_TraeIdEmpleadoBaja%notfound;
                        --dbms_output.put_line ('Empleado Dado de baja'|| v_baja.n_id_personal);
 
                        BEGIN --CUR APLICACIONES
                            OPEN cur_aplicaciones;
                                LOOP
                                    FETCH cur_aplicaciones INTO v_registro;
                                    EXIT WHEN cur_aplicaciones%notfound;
                                   UPDATE esquema.aplicaciones
                                    SET s_valor = REGEXP_REPLACE (v_registro.s_valor,('^(' || v_baja.n_id_personal || '),|,(' || v_baja.n_id_personal || ')$|^(' || v_baja.n_id_personal || ')$'),'')
                                    WHERE REGEXP_LIKE(v_registro.s_valor, ('^(' || v_baja.n_id_personal || '),|,(' || v_baja.n_id_personal || ')$|^(' || v_baja.n_id_personal || ')$'));*/ 
                                    --Elimina el id que se encuentre al inicio del registro, al final del registro o que sea el único valor en el registro
 
                                    UPDATE esquema.aplicaciones
                                    SET s_valor = REGEXP_REPLACE (v_registro.s_valor, ',(' || v_baja.n_id_personal || '),',',')
                                    WHERE REGEXP_LIKE(v_registro.s_valor,',(' || v_baja.n_id_personal || '),');
                                --Elimina el id que se encuentre en el medio del registro, rodeado por comas
 
                                END LOOP; --aplicaciones
                            END cur_aplicaciones;
                        CLOSE cur_aplicaciones;
                    END LOOP; --trae id empleado baja


ahora el problema es que no me esta recorriendo "s_valor". EStoy considerando cambiar el FETCH por un "FOR".

Gracias por tu ayuda y tu enorme paciencia
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar

¿Por qué mi procedimiento almacenado elimina los datos?

Publicado por Lena (14 intervenciones) el 08/10/2015 00:36:24
Ya cambié el FETCH por un ciclo FOR y funciona, pero sólo el primer UPDATE, al segundo no entra... toy buscando la razón
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
OPEN cur_TraeIdEmpleadoBaja;
                    LOOP
                        FETCH cur_TraeIdEmpleadoBaja INTO v_baja;
                        EXIT WHEN cur_TraeIdEmpleadoBaja%notfound;
 
                        BEGIN --CUR APLICACIONES
                        FOR v_registro
                        IN cur_aplicaciones
                            LOOP
                                    UPDATE esquema.aplicaciones
                                    SET s_valor = REGEXP_REPLACE (v_registro.s_valor, ',(' || v_baja.n_id_personal || '),',',')
                                    WHERE CURRENT OF cur_aplicaciones; --REGEXP_LIKE(v_registro.s_valor,',(' || v_baja.n_id_personal || '),');
                                    --Elimina el id que se encuentre en el medio del registro, rodeado por comas
 
                                    UPDATE esquema.aplicaciones
                                    SET s_valor = REGEXP_REPLACE (v_registro.s_valor, ('^(' || v_baja.n_id_personal || '), |,(' || v_baja.n_id_personal || ')$ |^(' || v_baja.n_id_personal || ')$'),'')
                                    WHERE CURRENT OF cur_aplicaciones;
                                   --Elimina el id que se encuentre al inicio del registro, al final del registro o que sea el único valor en el registro
 
                                END LOOP; --aplicaciones
                            END cur_aplicaciones;
                    END LOOP; --trae id empleado baja
           CLOSE cur_TraeIdEmpleadoBaja;
       END cur_TraeIdEmpleadoBaja;
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar

¿Por qué mi procedimiento almacenado elimina los datos?

Publicado por Lena (14 intervenciones) el 09/10/2015 20:36:39
Gracias por tu apoyo Rafael

Ya encontré el problema: Tuve que hacer los dos rexexp replace anidados:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
CREATE OR REPLACE PROCEDURE esquema.SP_AFTER_ESTATUS_BAJA_PRUEBA
--Este procedimiento almacenado elimina de la tabla aplicaciones a los empleados que ya fueron dados de baja
 
 IS
 BEGIN
        dbms_output.enable;
        DBMS_OUTPUT.ENABLE(10000000);
 
        DECLARE
        CURSOR cur_TraeIdEmpleadoBaja
        IS
            SELECT  n_id_personal
            FROM esquema.PERSONAL
            WHERE n_id_estatus = 9
            ORDER BY 1 ;
            v_baja cur_TraeIdEmpleadoBaja%rowtype;
 
       CURSOR cur_aplicaciones
       IS
            SELECT s_valor
            FROM esquema.aplicaciones
            WHERE REGEXP_LIKE(s_valor, ('^(' || v_baja.n_id_personal || '),|,(' || v_baja.n_id_personal || ')$|^(' || v_baja.n_id_personal || ')$|,(' || v_baja.n_id_personal || '),'))
            FOR UPDATE;
            v_registro cur_aplicaciones%rowtype;
 
       BEGIN
          OPEN cur_TraeIdEmpleadoBaja;
                    LOOP
                        FETCH cur_TraeIdEmpleadoBaja INTO v_baja;
                        EXIT WHEN cur_TraeIdEmpleadoBaja%notfound;
                        dbms_output.put_line ('Empleado Dado de baja'|| v_baja.n_id_personal);
                       BEGIN --CUR APLICACIONES
                        FOR v_registro
                        IN cur_aplicaciones
                            LOOP
                                   UPDATE esquema._aplicaciones
                                   SET s_valor = REGEXP_REPLACE (REGEXP_REPLACE (v_registro.s_valor, '^(' || v_baja.n_id_personal || '),|,(' || v_baja.n_id_personal || ')$|^(' || v_baja.n_id_personal || ')$',''),',(' || v_baja.n_id_personal || '),',',')
                                    WHERE CURRENT OF cur_aplicaciones;
                            END LOOP; --aplicaciones
                       END cur_aplicaciones;
                    END LOOP; --trae id empleado baja
           CLOSE cur_TraeIdEmpleadoBaja;
       END cur_TraeIdEmpleadoBaja;
  END SP_AFTER_ESTATUS_BAJA_PRUEBA;
 
/
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
1
Comentar