PDA

Ver la Versión Completa : Duda con trigger


santiago14
16-08-2014, 18:46:51
Buenas, les comento.

Tengo una tabla: Lotes

nro_lote:integer; (PK)
dimension:double precision;
estado_lote:varchar(50)


Un trigger sobre la tabla

CREATE trigger asociar_lote_cliente for lotes
active before update position 0
AS

begin
/* Solamente podemos asociar un cliente con un lote que esté DISPONIBLE */
if (new.estado_lote = 'OCUPADO' and old.estado_lote = 'OCUPADO') then
begin
exception lote_no_disponible;

end
end


Si queremos asociar un lote con un cliente, el mismo debe estar DISPONIBLE.
Hasta aquí todo bien, el trigger solamente me va a dejar pasar si el lote está disponible.

Resulta que ahora, por otra parte del software, se quiere modificar la dimensión del lote (que está en m2). Claramente eso no tiene nada que ver con el estado del lote.
Hago:

Update lotes set dimension = 350
Where nro_lote = 12


Al hacer esto, el trigger de mas arriba cancela la operación indicándome que el lote no está disponible.
El trigger se ejecuta "before", y en el update no estoy enviado ningún valor para el campo "estado_lote", por lo cual debería dejar que se haga la actualización sin problemas.
Lo que veo es que new y old tienen el mismo valor, sino no habría forma de que el if me de verdadero.
Esto es lo que me confunde... o yo estoy mal con esto o cambiaron las reglas de los triggers sin avisar. Se supone, que en este caso, el valor para new.estado_lote debería ser NULL o algo parecido pues no se actúa sobre él en el Update... Bah, no se.
Uso Firebird 2.5 y Delphi XE5.

Que alguien aclare please....

Gracias.

duilioisola
19-08-2014, 15:33:29
Las reglas no cambiaron, siempre fue así (por lo menos desde que era Interbase/Firebird 1.0.
Si algo no cambia, el new.value y el old.value serán iguales.

De todos modos no entiendo como haces la asociación. Supongo que has omitido el hecho de que la tabla lotes tiene también el cliente...
En ese caso, deberías verificar si esta disponible o no, solamente en el momento de asociar a un cliente. Quedaría algo así:

CREATE trigger asociar_lote_cliente for lotes
active before update position 0
AS
begin
/* Solamente si estoy modificando el cliente */
if (new.cliente <> old.cliente) then
begin
/* Solamente podemos asociar un cliente con un lote que esté DISPONIBLE */
if (new.estado_lote = 'OCUPADO' and old.estado_lote = 'OCUPADO') then
begin
exception lote_no_disponible;
end
end
end

santiago14
19-08-2014, 18:39:32
Exacto, obvié al cliente. Pero creo que ya di en la tecla. Igual les consulto...