PostgreSQL - ayuda con Trigger

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

ayuda con Trigger

Publicado por Davinson (1 intervención) el 11/05/2020 05:25:09
Necesito ayuda con el siguiente trigger, ocurre que no hace el cambio que deseo al momento de insertar o actualizar los datos en la tabla de alquiler no afectan a la tabla vehiculo; que es lo que deseo que ocurra. Por favor pido ayuda es simple pero no encuentro mi falla
Captura-2
Captura
En las imagenes se puede ver la situación planteada y mi código hasta el momento, cualquier ayuda sera bienvenida
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 Francisco
Val: 256
Oro
Ha mantenido su posición en PostgreSQL (en relación al último mes)
Gráfica de PostgreSQL

ayuda con Trigger

Publicado por Francisco (110 intervenciones) el 12/05/2020 18:14:37
Hola

Aqui tienes una posible respuesta


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
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
DROP TABLE IF EXISTS Vehiculo CASCADE;
CREATE TABLE Vehiculo
(
	placa Varchar(6) NOT NULL,
	color Varchar(20),
	modelo Varchar(20),
	marca Varchar(12),
	estadoVehiculo Varchar(10) DEFAULT 'Libre',
 CONSTRAINT pk_vehiculos PRIMARY KEY (placa)
);
 
DROP TABLE IF EXISTS Alquiler;
CREATE TABLE Alquiler
(
	idAlquiler Integer NOT NULL,
	fecha Date,
	numHoras Integer DEFAULT 0,
	valor Real DEFAULT 0,
	placaVehiculo Varchar(6) NOT NULL,
	estadoAlquiler Varchar(10) DEFAULT 'Iniciado',
 CONSTRAINT pk_alquiler PRIMARY KEY (idAlquiler)
);
 
ALTER TABLE Alquiler
	ADD FOREIGN KEY (placaVehiculo)
	REFERENCES Vehiculo (placa)
		ON UPDATE CASCADE
		ON DELETE RESTRICT;
 
/*
 * Este trigger valida que los dos estado posibles
 * para vehiculos sea 'Libre' o 'Alquilado' ANTES
 * de INSERTAR O ACTUALIZAR
 */
DROP FUNCTION IF EXISTS trigger_verificar_vehiculo_estado CASCADE;
CREATE OR REPLACE FUNCTION trigger_verificar_vehiculo_estado()
	RETURNS TRIGGER
AS
$$
DECLARE
BEGIN
	CASE TG_OP
		/* ********************************* */
		/* Permitimos insertar solo          */
		/* para estados de vehiculos validos */
		/* ********************************* */
		WHEN 'INSERT' THEN
			/*Validamos los estados del Vehiculo*/
			IF NEW.estadoVehiculo IN('Libre','Alquilado') THEN
				RETURN NEW;
			END IF;
			/* Informamos al usuario del problema */
			RAISE NOTICE 'ERROR: Problemas al insertar el vehiculo %. Estado del Vehículo Inválido => %',
					NEW.placa, NEW.estadoVehiculo;
			/* Rechazamos el registro */
			RETURN NULL;
		/* *************************************************** */
		/* Se ejecuta solo si hubo un cambio en estadoVehiculo */
		/* *************************************************** */
		WHEN 'UPDATE' THEN
			/* Validamos los estados del Vehiculo */
			IF NEW.estadoVehiculo IN('Libre','Alquilado') THEN
				/* Aceptamos el cambio */
				RETURN NEW;
			ELSE
				/* Informamos al usuario del problema */
				RAISE NOTICE 'ERROR: Problemas al actualizar el vehiculo %. Estado Vehículo Inválido => %',
					NEW.placa, NEW.estadoVehiculo;
			/*
			 * Se devuelve el registro original,
			 * pero mas efciente es un RETURN NULL
			 */
			RETURN OLD;
			END IF;
	END CASE;
	/* NO DEBERIA LLEGAR AQUI */
	RETURN NEW;
END
$$
LANGUAGE plpgsql;
 
DROP TRIGGER IF EXISTS trigger_vehiculo ON Vehiculo;
CREATE TRIGGER trigger_vehiculo
	/* Se ejecutara UPDATE solo si el valor de estadoVehiculo cambia */
	BEFORE INSERT OR UPDATE OF estadoVehiculo
	ON Vehiculo
	FOR EACH ROW
	EXECUTE FUNCTION trigger_verificar_vehiculo_estado();
 
/*
 * Este trigger valida que los dos estado posibles
 * para alquiler sea 'Iniciado' o 'Terminado' ANTES
 * de INSERTAR O ACTUALIZAR
 */
DROP FUNCTION IF EXISTS trigger_verificar_alquiler_estado CASCADE;
CREATE OR REPLACE FUNCTION trigger_verificar_alquiler_estado()
	RETURNS TRIGGER
AS
$$
DECLARE
	mi_placa varchar(6);
BEGIN
	/* ***************************************** */
	/* Si no existe la placa en maestra vehiculo */
	/* rechazamos cualquier operacion            */
	/* ***************************************** */
	SELECT placa INTO mi_placa
		FROM Vehiculo
		WHERE placa = NEW.placaVehiculo;
	IF NOT FOUND THEN
		RAISE NOTICE 'ERROR: La placa % no esta registrada en la maestra de Vehículos, No se insertara el registro. Verifíque por favor.',
			NEW.placaVehiculo;
		RETURN NULL;
	END IF;
 
	CASE TG_OP
		/* ********************************************************* */
		/* Permitimos insertar solo para estados de alquiler validos */
		/* ********************************************************* */
		WHEN 'INSERT' THEN
			/* Validamos los estados de alquiler */
			IF NEW.estadoAlquiler IN('Iniciado','Terminado') THEN
				CASE NEW.estadoAlquiler
					WHEN 'Iniciado' THEN
						UPDATE Vehiculo
							SET estadoVehiculo='Alquilado'
							WHERE placa = NEW.placaVehiculo;
					WHEN 'Terminado' THEN
						UPDATE Vehiculo
							SET estadoVehiculo='Libre'
							WHERE placa = NEW.placaVehiculo;
				END CASE;
				RETURN NEW;
			END IF;
			/* Informamos al usuario del problema */
			RAISE NOTICE 'ERROR: Problemas al insertar el estado de alquiler del vehiculo %. Estado de Alquiler Inválido => %',
				NEW.placaVehiculo, NEW.estadoAlquiler;
			/* Rechazamos el registro */
			RETURN NULL;
		/* *************************************************** */
		/* Se ejecuta solo si hubo un cambio en estadoAlquiler */
		/* *************************************************** */
		WHEN 'UPDATE' THEN
			/* Validamos los estados del Vehiculo */
			IF NEW.estadoAlquiler IN('Iniciado','Terminado') THEN
				CASE NEW.estadoAlquiler
					WHEN 'Iniciado' THEN
						UPDATE Vehiculo
							SET estadoVehiculo='Alquilado'
							WHERE placa = NEW.placavehiculo;
					WHEN 'Terminado' THEN
						UPDATE Vehiculo
							SET estadoVehiculo='Libre'
							WHERE placa = NEW.placavehiculo;
				END CASE;
				/* Aceptamos el cambio */
				RETURN NEW;
			END IF;
			/* Informamos al usuario del problema */
			RAISE NOTICE 'ERROR: Problemas al actualizar el estado de alquiler del vehiculo %. Estado de Alquiler Inválido => %',
				NEW.placaVehiculo, NEW.estadoAlquiler;
			/* Se devuelve el registro original, pero mas efciente es un RETURN NULL */
			RETURN OLD;
	END CASE;
	/* NO DEBERIA LLEGAR AQUI */
	RETURN NEW;
END
$$
LANGUAGE plpgsql;
 
DROP TRIGGER IF EXISTS trigger_alquiler ON alquiler;
CREATE TRIGGER trigger_aqluiler
	/* Se ejecutara UPDATE solo si el valor de estado alquiler cambia */
	BEFORE INSERT OR UPDATE OF estadoAlquiler
	ON Alquiler
	FOR EACH ROW
	EXECUTE FUNCTION trigger_verificar_alquiler_estado();
 
DO
$$
DECLARE
BEGIN
 
	RAISE NOTICE ' ';
	RAISE NOTICE '/* *********************************** */';
	RAISE NOTICE '/* >>>>>>>> TESTING VEHICULOS <<<<<<<< */';
	RAISE NOTICE '/* *********************************** */';
 
	RAISE NOTICE ' ';
	RAISE NOTICE '/* Insertando Vehículos... */';
	INSERT INTO Vehiculo(placa, color, modelo, marca)
		VALUES
			('AAA1','Amarillo','2020','Fiat'),
			('AAA2','AZul','2019','Fiat'),
			('ABA3','Rojo','2018','Honda'),
			('ABA4','Blanco','2017','Honda'),
			('ACA5','Negro','2020','Ford'),
			('ACA6','Verde','2019','Ford'),
			('ADA7','Cyan','2018','Chevrolet'),
			('ADA8','Gris','2017','Chevrolet'),
			('AEA9','Naranja','2020','Nissan');
 
	RAISE NOTICE ' ';
	RAISE NOTICE '/* Inserciones de Vehículos Rechazadas... */';
	/* Estos registro seran rechazados por el trigger */
	INSERT INTO Vehiculo(placa, color, modelo, marca, estadoVehiculo)
		VALUES
			('ABC10','Violeta','2020','Opel','Mtto'),
			('ABC11','Marron','2020','Saab','Operativo');
 
	/* Se actualiza correctamente por que no ha cambiado el estadoVehiculo */
	RAISE NOTICE ' ';
	RAISE NOTICE '/* Actualizando Vehículos... */';
	UPDATE Vehiculo SET modelo='2016' WHERE placa='AAA1';
	UPDATE Vehiculo SET modelo='2017' WHERE placa='AAA2';
 
	/* Estamos cambiando el valor estadoVehiculo pero seran rechazados */
	RAISE NOTICE ' ';
	RAISE NOTICE '/* Actualizaciones de Vehículos Rechazadas... */';
	UPDATE Vehiculo SET modelo='2015', estadoVehiculo='Operativo' WHERE placa='ABA3';
	UPDATE Vehiculo SET modelo='2014', estadoVehiculo='Mtto' WHERE placa='ABA4';
 
	RAISE NOTICE ' ';
	RAISE NOTICE '/* ************************************ */';
	RAISE NOTICE '/* >>>>>>>> TESTING ALQUILERES <<<<<<<< */';
	RAISE NOTICE '/* ************************************ */';
 
	RAISE NOTICE ' ';
	RAISE NOTICE '/* Insertando Alquileres... */';
	INSERT INTO Alquiler(idAlquiler, fecha, numhoras, valor, placaVehiculo, estadoAlquiler)
		VALUES
			(1, NOW()::date, 10, 100, 'AAA1', 'Iniciado'),
			(2, NOW()::date, 10, 100, 'AAA2', 'Iniciado'),
			(3, NOW()::date, 10, 100, 'ABA3', 'Iniciado'),
			(4, NOW()::date, 10, 100, 'ABA4', 'Iniciado'),
			(5, NOW()::date, 10, 100, 'ACA5', 'Terminado');
 
	RAISE NOTICE ' ';
	RAISE NOTICE '/* Inserciones rechazadas de Alquileres... */';
	/* Estos dos registro no se insertan por estados de alquiler inválidos */
	INSERT INTO Alquiler(idAlquiler, fecha, numhoras, valor, placaVehiculo, estadoAlquiler)
		VALUES
			(6, NOW()::date, 10, 100, 'ACA6', 'Intermedio'),
			(7, NOW()::date, 10, 100, 'ADA7', 'Intermedio');
 
	RAISE NOTICE ' ';
	RAISE NOTICE '/* Inserción rechazada: el vehículo no existe... */';
	/* Este registro nunca se insertara, placa no existe en la maestra de Vehículos */
	INSERT INTO Alquiler(idAlquiler, fecha, numhoras, valor, placaVehiculo, estadoAlquiler)
		VALUES
			(8, NOW()::date, 10, 100, 'AGA8', 'Terminado');
 
	/* ACTUALIZAMOS ALQUILERES */
	RAISE NOTICE ' ';
	RAISE NOTICE '/* Actualizacion de Alquileres... */';
	UPDATE Alquiler SET estadoAlquiler = 'Terminado' WHERE idAlquiler = 1;
	UPDATE Alquiler SET estadoAlquiler = 'Terminado' WHERE idAlquiler = 2;
 
	/* Se rechazan estas Actualizaciones */
	RAISE NOTICE ' ';
	RAISE NOTICE '/* Actualizacion rechazadas de Alquileres */';
	UPDATE Alquiler SET estadoAlquiler = 'Culminado' WHERE idAlquiler = 3;
	UPDATE Alquiler SET estadoAlquiler = 'Terminado' WHERE idAlquiler = 4;
 
	/* Se debe aceptar esta actualizacion */
	RAISE NOTICE ' ';
	RAISE NOTICE '/* Actualizacion valida de Alquileres... */';
	UPDATE Alquiler SET estadoAlquiler = 'Iniciado' WHERE idAlquiler = 5;
 
	/* No actualiza no existe la PK */
	RAISE NOTICE ' ';
	RAISE NOTICE '/* Actualizacion rechazada por PK inexistente... */';
	UPDATE Alquiler SET estadoAlquiler = 'Iniciado' WHERE idAlquiler = 20;
END
$$
LANGUAGE plpgsql;

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