Oracle - Incapaz de que salga este Trigger

 
Vista:
sin imagen de perfil

Incapaz de que salga este Trigger

Publicado por Trillante (3 intervenciones) el 15/05/2018 01:38:04
Hola buenas, resulta que haciendo un Trigger destinado a un proyecto, soy incapaz de que salgan los resultados esperados y ya llevo tiempo intentándolo :/
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
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
DROP TABLE trabajador CASCADE CONSTRAINTS;
 
DROP TABLE establecimiento CASCADE CONSTRAINTS;
 
DROP TABLE hora_apertura CASCADE CONSTRAINTS;
 
DROP TABLE trabajador_no_disponible CASCADE CONSTRAINTS;
 
DROP TABLE contrato CASCADE CONSTRAINTS;
 
DROP TABLE tipo_contrato CASCADE CONSTRAINTS;
 
DROP TABLE sueldo_mensual CASCADE CONSTRAINTS;
 
DROP TABLE venta_empleado CASCADE CONSTRAINTS;
 
DROP TABLE turno_plan CASCADE CONSTRAINTS;
 
DROP TABLE turno_real CASCADE CONSTRAINTS;
 
CREATE TABLE trabajador (
    id_trabajador         SMALLINT NOT NULL,
    nombre_trabajador     VARCHAR(50) NOT NULL,
    apellido_trabajador   VARCHAR(50) NOT NULL,
    tipo_trabajador       VARCHAR2(50) CHECK ( tipo_trabajador IN (
        'camarero_copas',
        'camarero_cafe',
        'camarero_restaurante',
        'cocinero'
    ) ),
    dni                   CHAR(9) NOT NULL,
    telefono              NUMERIC(9) NOT NULL,
    email                 VARCHAR(50) NOT NULL UNIQUE,
    direccion             VARCHAR(50) NOT NULL,
    seguridad_social      CHAR(20) NOT NULL UNIQUE,
    datos_bancarios       VARCHAR(50) NOT NULL,
    PRIMARY KEY ( id_trabajador )
);
 
CREATE TABLE establecimiento (
    id_establecimiento       SMALLINT NOT NULL,
    nombre_establecimiento   VARCHAR(50) NOT NULL,
    tipo_establecimiento     VARCHAR2(30) CHECK ( tipo_establecimiento IN (
        'Copas',
        'Cafeteria',
        'Restaurante'
    ) ),
    PRIMARY KEY ( id_establecimiento )
);
 
CREATE TABLE hora_apertura (
    id_hora_apertura     SMALLINT NOT NULL,
    dia                  DATE NOT NULL,
    hora_apertura        DATE NOT NULL,
    hora_cierre          DATE NOT NULL,
    id_establecimiento   SMALLINT NOT NULL,
    PRIMARY KEY ( id_hora_apertura ),
    FOREIGN KEY ( id_establecimiento )
        REFERENCES establecimiento
            ON DELETE CASCADE
);
 
CREATE TABLE trabajador_no_disponible (
    id_trabajador_nd   SMALLINT NOT NULL,
    tipo_ausencia      VARCHAR2(50) CHECK ( tipo_ausencia IN (
        'Vacaciones',
        'Enfermedad'
    ) ),
    fecha_inicio       DATE,
    fecha_fin          DATE,
    id_trabajador      SMALLINT NOT NULL,
    PRIMARY KEY ( id_trabajador_nd ),
    FOREIGN KEY ( id_trabajador )
        REFERENCES trabajador
            ON DELETE CASCADE
);
 
CREATE TABLE tipo_contrato (
    id_tipo_c       SMALLINT NOT NULL,
    sueldo          NUMERIC(12,2) CHECK ( sueldo > 735.90 ),
    tipo_contrato   VARCHAR2(30) CHECK ( tipo_contrato IN (
        'Indefinido',
        'Por horas'
    ) ),
    PRIMARY KEY ( id_tipo_c )
);
 
CREATE TABLE contrato (
    id_contrato     SMALLINT NOT NULL,
    fecha_alta      DATE NOT NULL,
    fecha_fin       DATE,
    id_trabajador   SMALLINT NOT NULL,
    id_tipo_c       SMALLINT NOT NULL,
    PRIMARY KEY ( id_contrato ),
    FOREIGN KEY ( id_trabajador )
        REFERENCES trabajador
            ON DELETE CASCADE,
    FOREIGN KEY ( id_tipo_c )
        REFERENCES tipo_contrato
            ON DELETE CASCADE
);
 
CREATE TABLE sueldo_mensual (
    id_sueldo_mensual    SMALLINT NOT NULL,
    sueldo_mensual       NUMERIC(12,2),
    horas_extra          SMALLINT NOT NULL,
    mes                  DATE,
    precio_horas_extra   SMALLINT NOT NULL,
    id_contrato          SMALLINT NOT NULL,
    PRIMARY KEY ( id_sueldo_mensual ),
    FOREIGN KEY ( id_contrato )
        REFERENCES contrato
            ON DELETE CASCADE
);
 
CREATE TABLE venta_empleado (
    id_venta_empleado    SMALLINT NOT NULL,
    fecha                DATE NOT NULL,
    cantidad             NUMERIC(12,2),
    id_trabajador        SMALLINT NOT NULL,
    id_establecimiento   SMALLINT NOT NULL,
    PRIMARY KEY ( id_venta_empleado ),
    FOREIGN KEY ( id_trabajador )
        REFERENCES trabajador
            ON DELETE CASCADE,
    FOREIGN KEY ( id_establecimiento )
        REFERENCES establecimiento
);
 
CREATE TABLE turno_plan (
    id_turno_plan        SMALLINT NOT NULL,
    dia                  DATE NOT NULL,
    hora_inicio          DATE NOT NULL,
    hora_fin             DATE NOT NULL,
    id_establecimiento   SMALLINT NOT NULL,
    id_trabajador        SMALLINT NOT NULL,
    PRIMARY KEY ( id_turno_plan ),
    FOREIGN KEY ( id_trabajador )
        REFERENCES trabajador,
    FOREIGN KEY ( id_establecimiento )
        REFERENCES establecimiento
);
 
CREATE TABLE turno_real (
    id_turno_real   SMALLINT NOT NULL,
    id_turno_plan   SMALLINT NOT NULL,
    hora_inicio     DATE NOT NULL,
    hora_fin        DATE NOT NULL,
    dia             DATE NOT NULL,
    PRIMARY KEY ( id_turno_real ),
    FOREIGN KEY ( id_turno_plan )
        REFERENCES turno_plan
);

----------------------------------Idea de mi Trigger----------------------------------------
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
CREATE OR REPLACE TRIGGER sueldoderivado AFTER
    INSERT ON sueldo_mensual
    FOR EACH ROW
DECLARE
    varsuel   NUMBER;
BEGIN
    FOR c IN (
        SELECT
            sueldo
        FROM
            tipo_contrato,
            contrato
        WHERE
            tipo_contrato.id_tipo_c = contrato.id_tipo_c
    ) LOOP
        UPDATE sueldo_mensual
            SET
                sueldo_mensual = precio_horas_extra * horas_extra + c.sueldo;
 
    END LOOP;
END;
/
 
ALTER TRIGGER sueldoderivado ENABLE;

------------------------------Inserciones-----------------------------
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
delete tipo_contrato;
delete contrato;
delete sueldo_mensual;
delete trabajador;
insert into trabajador values ('1','Paco','Gomez','cocinero', '49167843H', '1238921','1283192','128931','1231231','123123');
insert into trabajador values ('2','Paco','Gomez','cocinero', '49167843H', '1238921','12312','128931','123123','123123');
insert into trabajador values ('3','Paco','Gomez','cocinero', '49167843H', '1238921','1287381','128931','8172381','123123');
insert into tipo_contrato values('1','1000', 'Indefinido');
insert into tipo_contrato values('2','1340', 'Indefinido');
insert into tipo_contrato values('3','2440', 'Indefinido');
insert into contrato values('1',TO_DATE(SYSDATE), TO_DATE(SYSDATE), '1', '1');
insert into contrato values('2',TO_DATE(SYSDATE), TO_DATE(SYSDATE), '2', '2');
insert into contrato values('3',TO_DATE(SYSDATE), TO_DATE(SYSDATE), '3', '3');
insert into sueldo_mensual values('1','0','6',TO_DATE(SYSDATE),'110','1');
insert into sueldo_mensual values('2','0','5',TO_DATE(SYSDATE),'15','2');
insert into sueldo_mensual values('3','0','5',TO_DATE(SYSDATE),'25','2');

-----ERROR, harto de buscar por Google y aún no soy capaz de dar con una solución adaptada a mi problema----
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
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
1 fila insertadas.
 
 
1 fila insertadas.
 
 
1 fila insertadas.
 
 
1 fila insertadas.
 
 
1 fila insertadas.
 
 
1 fila insertadas.
 
 
3 filas eliminado
 
 
0 filas eliminado
 
 
0 filas eliminado
 
 
3 filas eliminado
 
 
1 fila insertadas.
 
 
1 fila insertadas.
 
 
1 fila insertadas.
 
 
1 fila insertadas.
 
 
1 fila insertadas.
 
 
1 fila insertadas.
 
 
1 fila insertadas.
 
 
1 fila insertadas.
 
 
1 fila insertadas.
 
 
Error que empieza en la línea: 14 del comando :
insert into sueldo_mensual values('1','0','6',TO_DATE(SYSDATE),'110','1')
Informe de error -
ORA-04091: table PRUEBAS.SUELDO_MENSUAL is mutating, trigger/function may not see it
ORA-06512: at "PRUEBAS.SUELDODERIVADO", line 6
ORA-04088: error during execution of trigger 'PRUEBAS.SUELDODERIVADO'
 
 
Error que empieza en la línea: 15 del comando :
insert into sueldo_mensual values('2','0','5',TO_DATE(SYSDATE),'15','2')
Informe de error -
ORA-04091: table PRUEBAS.SUELDO_MENSUAL is mutating, trigger/function may not see it
ORA-06512: at "PRUEBAS.SUELDODERIVADO", line 6
ORA-04088: error during execution of trigger 'PRUEBAS.SUELDODERIVADO'
 
 
Error que empieza en la línea: 16 del comando :
insert into sueldo_mensual values('3','0','5',TO_DATE(SYSDATE),'25','2')
Informe de error -
ORA-04091: table PRUEBAS.SUELDO_MENSUAL is mutating, trigger/function may not see it
ORA-06512: at "PRUEBAS.SUELDODERIVADO", line 6
ORA-04088: error during execution of trigger 'PRUEBAS.SUELDODERIVADO'

La idea era actualizar Sueldo mensual de cada fila aplicando la operación Precio_horas_extra * Horas_extra + c.sueldo, pero no soy capaz de implementar dicha operación de manera correcta.
He intentado sin for each row, pero así se guarda el valor del bucle y no actualiza el Sueldo Mensual con el valor correcto.


Muchas gracias!!
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
Imágen de perfil de gilman
Val: 117
Bronce
Ha mantenido su posición en Oracle (en relación al último mes)
Gráfica de Oracle

Incapaz de que salga este Trigger

Publicado por gilman (52 intervenciones) el 16/05/2018 08:18:28
No se pueden ejecutar sentencias SQL sobre la tabla, o tablas, que están siendo modificadas cuando se ejecute el trigger, en tu caso la sentencia:
1
2
3
UPDATE sueldo_mensual
SET
sueldo_mensual = precio_horas_extra * horas_extra + c.sueldo;

se ejecuta sobre la tabla que proboca el trigger, de ahí el error devuelto.
para acceder a los campos de la tabla que proboca el trigger se utiliza el nobre del campo precedido por :NEW. o :OLD. según se quiera acceder al nuevo valor del campo o al viejo en tú caso la sentencia debería quedar:
1
:NEW.sueldo_mensual = :NEW.precio_horas_extra * :NEW.horas_extra + c.sueldo;
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