Oracle - Trigger que no actualiza

 
Vista:
sin imagen de perfil
Val: 1
Ha disminuido su posición en 33 puestos en Oracle (en relación al último mes)
Gráfica de Oracle

Trigger que no actualiza

Publicado por Lena (15 intervenciones) el 24/09/2015 19:16:57
Tengo que hacer un trigger que cuando un empleado de la tabla personal cambie su estatus a 9 (baja), ese ID sea eliminado de un campo de la tabla aplicaciones, pero este campo tiene valores como 10001,40000,40,7,8 si, digamos, elimino el empleado 40, debe quedar como 10001,40000,7,8, hice el siguiente trigger que ya compila, pero cuando cambio el estatus del empleado no actualiza y no me marca error...

¿por dónde le busco?

Agradezco cualquier pista

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
CREATE OR REPLACE TRIGGER TG_BAJA_PERSONAL
   AFTER UPDATE OF n_id_estatus
   ON  PERSONAL
   FOR EACH ROW
WHEN (
new.n_id_estatus = 9
      )
DECLARE
PRAGMA AUTONOMOUS_TRANSACTION;
 v_idPer number;
BEGIN
    DBMS_OUTPUT.ENABLE(10000000);
   SELECT n_id_personal INTO v_idPer FROM PERSONAL
   WHERE :NEW.n_id_estatus = 9;
 
   dbms_output.put_line ('Valor de id_personal: '|| v_idPer);
 
commit;
 
   EXCEPTION
    WHEN OTHERS THEN
    DBMS_OUTPUT.PUT_LINE( SQLERRM );
 
END;
/
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
sin imagen de perfil
Val: 499
Oro
Ha mantenido su posición en Oracle (en relación al último mes)
Gráfica de Oracle

Trigger que no actualiza

Publicado por Rafael (328 intervenciones) el 25/09/2015 10:49:12
Cuando dices que no actualiza es que no le cambia el status? o que no borra de la tabla aplicaciones.

Si no Actualiza seguramente envia mensaje de error pero ... como lo que haces es un DBMS_OUTPUT seguro no lo ves si antes de hacer el update no le dices:
1
SET SERVEROUTPUT ON


Ahora bien si cambia el status pero no borro la info de la tabla aplicaciones es por que no has puesto el delete.

Saludos
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
sin imagen de perfil
Val: 1
Ha disminuido su posición en 33 puestos en Oracle (en relación al último mes)
Gráfica de Oracle

Trigger que no actualiza

Publicado por Lena (15 intervenciones) el 28/09/2015 15:25:16
Sí, gracias por la observación, por error copié el código sin una parte. lo pongo 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
CREATE OR REPLACE TRIGGER TG_BAJA_PERSONAL
 
   AFTER UPDATE OF n_id_estatus
   ON personal
   FOR EACH ROW
WHEN (
NEW.n_id_estatus = 9
      )
DECLARE
   PRAGMA AUTONOMOUS_TRANSACTION;
   v_idper   NUMBER;
BEGIN
 
   SELECT n_id_personal
     INTO v_idper
     FROM personal
    WHERE n_id_personal = :OLD.n_id_personal;
 
   UPDATE aplicaciones
      SET s_valor =
             DECODE (aplicaciones.s_valor,
                     ',' || v_idper || ',', '' || v_idper || ',',
                     (REGEXP_REPLACE (aplicaciones.s_valor,
                                      '^(' || v_idper || '),|,(' || v_idper
                                      || ')'
                                     )
                     )
                    )
    WHERE REGEXP_LIKE (s_valor,
                          '^('
                       || v_idper
                       || '),|,('
                       || v_idper
                       || ')+,|,('
                       || v_idper
                       || ')$'
                      );
 
   DBMS_OUTPUT.put_line ('FECHA Fin: ' || v_idper);
   COMMIT;
EXCEPTION
   WHEN OTHERS
   THEN
      DBMS_OUTPUT.put_line (SQLERRM);
END;
/
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
sin imagen de perfil
Val: 499
Oro
Ha mantenido su posición en Oracle (en relación al último mes)
Gráfica de Oracle

Trigger que no actualiza

Publicado por Rafael (328 intervenciones) el 29/09/2015 14:05:41
a ver nuevas cosas y detalles a comentar:

1. Haces una consulta que no te sirve de nada...
1
2
3
4
SELECT n_id_personal
     INTO v_idper
     FROM personal
    WHERE n_id_personal = :OLD.n_id_personal;

Aqui vas a recuperar en la misma tabla que estas actualizando (OJO ESTA MUTANDO), el ID que es igual al OLD. El trigger solo se dispara al cambio del campo "n_id_estatus" luego entonces el OLD y NEW del campo "n_id_personal" seran el mismo, pero si consultas lo mismo que ya tienes este query no sirve de nada.

Vaya espero que entiendas como esto afecta al performance y posiblemente este enviando desde aqui un mensaje de error.

2. Usas la funcion "REGEXP_REPLACE", le dices la cadena y que buscar (una expresion regular que armas al vuelo con el numero del id personal, pero no le dices con que reemplazaras dicha cadena.... Vaya es posible usarlo asi pero a mi me queda como inconcluso.

3. Si ocurre una excepción no haces ROLLBACk, entoces para que lo encapsulas en una PRAGMA AUTONOMOUS_TRANSACTION?

Bueno en resumen yo lo dejaria asi:
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
CREATE OR REPLACE TRIGGER TG_BAJA_PERSONAL
    AFTER UPDATE OF n_id_estatus
    ON personal
    FOR EACH ROW
    WHEN (NEW.n_id_estatus = 9)
DECLARE
   PRAGMA AUTONOMOUS_TRANSACTION;
 
   v_idper   NUMBER;
 
BEGIN
    UPDATE aplicaciones
    SET s_valor =
                    DECODE (aplicaciones.s_valor,
                            ',' || :OLD.n_id_personal || ',', '' || :OLD.n_id_personal || ',',
                            REGEXP_REPLACE (aplicaciones.s_valor,
                                          '^(' || :OLD.n_id_personal || '),|,(' || :OLD.n_id_personal|| ')',
                                          '')
                    )
    WHERE REGEXP_LIKE (s_valor, '^(' || v_idper || '),|,(' || v_idper || ')+,|,(' || v_idper || ')$');
    DBMS_OUTPUT.put_line ('FECHA Fin: ' || v_idper);
    COMMIT;
 
EXCEPTION
    WHEN OTHERS THEN
        DBMS_OUTPUT.put_line (SQLERRM);
        ROLLBACK;
END;
/

Y para probarlo haria algo asi desde el sqlplus:
1
2
SET SERVEROUTPUT ON
UPDATE personal SET n_id_estatus = 9 WHERE n_id_personal = 1;
Asi si ocurriese un error lo veria...


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
sin imagen de perfil
Val: 1
Ha disminuido su posición en 33 puestos en Oracle (en relación al último mes)
Gráfica de Oracle

Trigger que no actualiza

Publicado por Lena (15 intervenciones) el 29/09/2015 19:47:47
Gracias Rafael por tu sugerencia.

La consulta la hago para que me guarde el id del registro que acaba de actualizarse, la expresion regular la utilizo para que me busque ese id, pero precedido, rodeado o finalizado en coma. El detalle es que no me esta actualizando porque una de las expresiones regulares esta mal...

Ahora pruebo tu sugerencia y te comento. Gracias por tomarte el tiempo de orientarme.
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
sin imagen de perfil
Val: 1
Ha disminuido su posición en 33 puestos en Oracle (en relación al último mes)
Gráfica de Oracle

Trigger que no actualiza

Publicado por Lena (15 intervenciones) el 29/09/2015 23:33:26
Ya probé los cambios que me hiciste favor de comentarme, pero no me hace bien la actualización si tengo estos valores:
17,19,54,1,289,224 y elimino el 1, me queda 54,289,224

El regexp replace no lleva un tercer parámetro porque por default cuando no lo lleva, se le dice que elimine el valor que encontró.

Agradezco tu ayuda!
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
sin imagen de perfil
Val: 499
Oro
Ha mantenido su posición en Oracle (en relación al último mes)
Gráfica de Oracle

Trigger que no actualiza

Publicado por Rafael (328 intervenciones) el 30/09/2015 08:25:50
Insisto que la consulta esta demas, por que es un valor que ya tienes, para que lo vuelves a preguntar???
Bueno y al corregir las expresiones que paso ???

Como la has dejado???
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
sin imagen de perfil
Val: 1
Ha disminuido su posición en 33 puestos en Oracle (en relación al último mes)
Gráfica de Oracle

Trigger que no actualiza

Publicado por Lena (15 intervenciones) el 30/09/2015 18:51:54
Probé con la sugerencia que me hiciste:
1
2
3
4
5
6
UPDATE esquema.aplicaciones
    SET s_valor =
                    DECODE (esquema.aplicaciones.s_valor,
                            ',' || :OLD.n_id_personal || ',', '' || :OLD.n_id_personal || ',',
                            REGEXP_REPLACE (esquema.aplicaciones.s_valor,
                                          '^(' || :OLD.n_id_personal || '),|,(' || :OLD.n_id_personal|| ')')
pero si tengo 54,19,5 al cambiar de estatus el 19 me deja 545.

Después lo hice con un IF, pero no actualiza:
1
2
3
4
5
6
7
8
9
IF (REGEXP_LIKE('esquema.aplicaciones.s_valor', '^(' || :OLD.n_id_personal || '),|,(' || :OLD.n_id_personal || ')+,|,(' || :OLD.n_id_personal || ')$'))
    THEN
        IF (REGEXP_LIKE('esquema.aplicaciones.s_valor', '^(' || :OLD.n_id_personal || '),'))
        THEN
            UPDATE esquema.aplicaciones
            SET s_valor = REGEXP_REPLACE (esquema.aplicaciones.s_valor','^(' || :OLD.n_id_personal || '),','')
                    WHERE REGEXP_LIKE ('esquema.aplicaciones.s_valor', '^(' || :OLD.n_id_personal || '),');
        END IF;

Con los tres if dentro del primero
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
sin imagen de perfil
Val: 1
Ha disminuido su posición en 33 puestos en Oracle (en relación al último mes)
Gráfica de Oracle

Trigger que no actualiza

Publicado por Lena (15 intervenciones) el 02/10/2015 15:54:49
Muchas gracias por tu apoyo Rafael, tu orientación me ayudó mucho y al final quedó así:

1
2
3
4
5
6
7
8
9
10
11
12
BEGIN
    UPDATE esquema.aplicaciones
    SET s_valor = REGEXP_REPLACE (esquema.aplicaciones.s_valor, ('^(' || :OLD.n_id_personal || '),|,(' || :OLD.n_id_personal || ')$|^(' || :OLD.n_id_personal || ')$'),'')
    WHERE REGEXP_LIKE(esquema.aplicaciones.s_valor, ('^(' || :OLD.n_id_personal || '),|,(' || :OLD.n_id_personal || ')$|^(' || :OLD.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.tb_cfg_aplicaciones
    SET s_valor = REGEXP_REPLACE (esquema.aplicaciones.s_valor, ',(' || :OLD.n_id_personal || '),',',')
    WHERE REGEXP_LIKE(esquema.aplicaciones.s_valor, ',(' || :OLD.n_id_personal || '),');
    --Elimina el id que se encuentre en el medio del registro, rodeado por comas (sustituye coma valor coma por una sola coma)
 
COMMIT;

Utilicé la variable como me la pusiste y también la excepción que me sugeriste. Corre perfecto
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