Foros del Web » Programación para mayores de 30 ;) » Bases de Datos General »

disparador duda

Estas en el tema de disparador duda en el foro de Bases de Datos General en Foros del Web. Buenas, necesito ayuda con este tema, quiero hacer un disparador para que me numere cada vez que se haga update y campo Status sea = ...
  #1 (permalink)  
Antiguo 16/06/2016, 07:29
 
Fecha de Ingreso: abril-2016
Mensajes: 90
Antigüedad: 8 años, 8 meses
Puntos: 1
disparador duda

Buenas, necesito ayuda con este tema, quiero hacer un disparador para que me numere cada vez que se haga update y campo Status sea = "Enviado".

campo idal es el campo que ha de numerarse, el valor inicial es 0000
la otra condición es (esto si es posible)
en el campo centro tengo valores desde T1 a Txx

quisiera que la numeración no solo fuese el siguiente numero sino por cada centro, si hay tres T1 con status=Enviado que numere del 1 al 3 , y si hay 8 status=Enviado en T9 que numere 1 al 8 (esto si se puede sino me conformo con una numeración correlativa)

nombre:numerar
Tabla: envios
después de
evento update
SET idal = SELECT MAX(idal) FROM pedidos where status=Enviado;

gracias de antemano
  #2 (permalink)  
Antiguo 16/06/2016, 07:51
Avatar de gnzsoloyo
Moderador criollo
 
Fecha de Ingreso: noviembre-2007
Ubicación: Actualmente en Buenos Aires (el enemigo ancestral)
Mensajes: 23.324
Antigüedad: 17 años
Puntos: 2658
Respuesta: disparador duda

¿Cuál DBMS?

El código no se escribe de la misma forma si es Oracle, SQL Server, MySQL o lo que fuere.
__________________
¿A quién le enseñan sus aciertos?, si yo aprendo de mis errores constantemente...
"El problema es la interfase silla-teclado." (Gillermo Luque)
  #3 (permalink)  
Antiguo 16/06/2016, 07:51
 
Fecha de Ingreso: abril-2016
Mensajes: 90
Antigüedad: 8 años, 8 meses
Puntos: 1
Respuesta: disparador duda

Perdón mysql
  #4 (permalink)  
Antiguo 16/06/2016, 09:22
Avatar de gnzsoloyo
Moderador criollo
 
Fecha de Ingreso: noviembre-2007
Ubicación: Actualmente en Buenos Aires (el enemigo ancestral)
Mensajes: 23.324
Antigüedad: 17 años
Puntos: 2658
Respuesta: disparador duda

Perfecto...
¿Qué tanto tienes hecho? ¿Has probado programar alguna vez un trigger en MySQL?
¿Seguiste algún ejemplo del manual de referencia?

Es mejro haber hecho aunque sea una prueba falida, antes que darte el codigo resuelto. Se aprende mas.

Postea lo que hayas intentado y dinos qué problema tienes o qué error te dispara.
__________________
¿A quién le enseñan sus aciertos?, si yo aprendo de mis errores constantemente...
"El problema es la interfase silla-teclado." (Gillermo Luque)
  #5 (permalink)  
Antiguo 16/06/2016, 12:50
 
Fecha de Ingreso: abril-2016
Mensajes: 90
Antigüedad: 8 años, 8 meses
Puntos: 1
Respuesta: disparador duda

buenas, no si ya lo he intentado, con esta sentencia SET idal = SELECT MAX(idal) FROM pedidos where status=Enviado;
desde phpmyadmin en la ventana de disparadores, y o bien me da errores 1169 10xx (ahora no recuerdo o simplemente se queda ejecutando pero no hace nada.
No pretendo que nadie me dé la solución sin mas pretendo entenderlo, porque seguro que necesitaré mas.
gracias
  #6 (permalink)  
Antiguo 16/06/2016, 13:21
Avatar de gnzsoloyo
Moderador criollo
 
Fecha de Ingreso: noviembre-2007
Ubicación: Actualmente en Buenos Aires (el enemigo ancestral)
Mensajes: 23.324
Antigüedad: 17 años
Puntos: 2658
Respuesta: disparador duda

Cita:
Iniciado por fab2160225 Ver Mensaje
buenas, no si ya lo he intentado, con esta sentencia SET idal = SELECT MAX(idal) FROM pedidos where status=Enviado;
desde phpmyadmin en la ventana de disparadores, y o bien me da errores 1169 10xx (ahora no recuerdo o simplemente se queda ejecutando pero no hace nada.
No pretendo que nadie me dé la solución sin mas pretendo entenderlo, porque seguro que necesitaré mas.
gracias
Cuando te digo
Cita:
Postea lo que hayas intentado y dinos qué problema tienes o qué error te dispara.
Me refiero a que postees el código completo de lo que codificaste, no a que nos describas las cosas.
CODIGO, no descripciones
.
Quiero imaginar que lo que escribiste en ese "trigger" no fue simplemente ese SET... ¿No es así?
__________________
¿A quién le enseñan sus aciertos?, si yo aprendo de mis errores constantemente...
"El problema es la interfase silla-teclado." (Gillermo Luque)
  #7 (permalink)  
Antiguo 16/06/2016, 13:35
 
Fecha de Ingreso: abril-2016
Mensajes: 90
Antigüedad: 8 años, 8 meses
Puntos: 1
Respuesta: disparador duda

Buenas, si te he entendido, en la ventana que digo de phpmyadmin disparadores ya existen unos campos
1º nombre que se refiere al nombre que se le quiere dar al trigger
2º antes / después que se refiere a cuando se debe ejecutar
3º into , update, etc con que sentencia debe ejecutarse

luego queda otro campo que es el cuerpo por así decirlo, por eso solo e puesto esa parte, espero haberme explicado.
gracias
  #8 (permalink)  
Antiguo 16/06/2016, 13:37
 
Fecha de Ingreso: abril-2016
Mensajes: 90
Antigüedad: 8 años, 8 meses
Puntos: 1
Respuesta: disparador duda

Buenas en este enlace tienes una imagen de lo que describo:
Cita:
http://likonet.es/likonet/ejemplo-de-creacion-triggers-mysq/
  #9 (permalink)  
Antiguo 17/06/2016, 00:35
 
Fecha de Ingreso: abril-2016
Mensajes: 90
Antigüedad: 8 años, 8 meses
Puntos: 1
Respuesta: disparador duda

Buenas, he estado mirando y la cabecera debería ser la siguiente, pero donde fallo es en el cuerpo (creo)

Código SQL:
Ver original
  1. CREATE TRIGGER numerar
  2. AFTER UPDATE ON envios
  3. FOR EACH ROW
  4. BEGIN
  5. UPDATE pedidos
  6. SET idal = SELECT MAX(idal)+1 FROM pedidos WHERE STATUS=Enviado;


Gracias

Última edición por gnzsoloyo; 17/06/2016 a las 06:15
  #10 (permalink)  
Antiguo 17/06/2016, 01:31
 
Fecha de Ingreso: abril-2016
Mensajes: 90
Antigüedad: 8 años, 8 meses
Puntos: 1
Respuesta: disparador duda

Buenas, si ejecuto esto sin mas me enumeraría todo aquello que cumpliese la condición, si añado un by group status para intentar que aquellos que cumplan la condición tengan el mismo numero me da error

Código SQL:
Ver original
  1. SET @numero=0;
  2. SELECT @numero:=@numero+1 AS `idal`.* FROM `pedidos` WHERE `status`= "Enviado";
(este numera todo )

Código SQL:
Ver original
  1. SET @numero=0;
  2. SELECT @numero:=@numero+1 AS `idal`.* FROM `pedidos` WHERE `status`= "Enviado"  GROUP BY `status`;
(este me da error)

Última edición por gnzsoloyo; 17/06/2016 a las 06:15
  #11 (permalink)  
Antiguo 17/06/2016, 02:44
 
Fecha de Ingreso: abril-2016
Mensajes: 90
Antigüedad: 8 años, 8 meses
Puntos: 1
Respuesta: disparador duda

buenas, he llegado hasta aquí pero no funciona me dice que el operador debe tener una columna


Código SQL:
Ver original
  1. SELECT MAX( `idal` ) +1 AS `idal`, `status`, `fecha`,`articulos` FROM `pedidos` WHERE `idal`= (SELECT `idal`,`status` , `fecha` , `articulos`
  2. FROM `pedidos`
  3. WHERE `status` = "Enviado");

esto sería la unión de:
Código SQL:
Ver original
  1. SELECT MAX( `idal` ) +1 `idal`
  2. FROM `pedidos`
que me daría el siguiente numero

y:
Código SQL:
Ver original
  1. SELECT `status` , `fecha` , `articulos`
  2. FROM `pedidos`
  3. WHERE `status` = "Enviado"
  4. AND `idal` = ""
que indica en que campos a de poner ese numero.


gracias

Última edición por gnzsoloyo; 17/06/2016 a las 06:14
  #12 (permalink)  
Antiguo 17/06/2016, 06:45
Avatar de gnzsoloyo
Moderador criollo
 
Fecha de Ingreso: noviembre-2007
Ubicación: Actualmente en Buenos Aires (el enemigo ancestral)
Mensajes: 23.324
Antigüedad: 17 años
Puntos: 2658
Respuesta: disparador duda

Bueno, volvamos al principio, para que se entienda claramente que tienes algunos inconvenientes básicos para crear el trigger, y están en tu diseño de datos...

Voy a suponer (siempre es bueno primero que nos describas qué es lo que quieres hacer, técnicamente), que lo que quieres es registrar la cantidad de envíos de un pedido dado, y los envíos se registran en una tabla separada a la que denominas "Envios".

Según dices en el primer post:

Cita:
Buenas, necesito ayuda con este tema, quiero hacer un disparador para que me numere cada vez que se haga update y campo Status sea = "Enviado".
Un sistema que registre los envíos, para tener trazabilidad de los envíos, no debería actualizar un registro, sino INSERTAR uno nuevo por cada envío.

Cita:
campo idal es el campo que ha de numerarse, el valor inicial es 0000
la otra condición es (esto si es posible)
en el campo centro tengo valores desde T1 a Txx
Si el campo es alfanumérico, es decir que puede ir del "T1" al "T99" como dices, no es posible usarlo para operaciones aritméticas, sencillamente porque no se pueden SUMAR valores numéricos a una cadena de texto. La parte de cadena daría cero en la conversión implícita, dejando solo el numero a sumar:
Código MySQL:
Ver original
  1. mysql> SELECT ('T01' + 2) resultado;
  2. +-----------+
  3. | resultado |
  4. +-----------+
  5. |         2 |
  6. +-----------+
  7. 1 row in set, 1 warning (0.01 sec)

y si sumas cadenas que contengan letras, devuelve cero:

Código MySQL:
Ver original
  1. mysql> SELECT ('T01' + 'T02') resultado;
  2. +-----------+
  3. | resultado |
  4. +-----------+
  5. |         0 |
  6. +-----------+
  7. 1 row in set, 2 warnings (0.00 sec)

Cita:
quisiera que la numeración no solo fuese el siguiente numero sino por cada centro, si hay tres T1 con status=Enviado que numere del 1 al 3 , y si hay 8 status=Enviado en T9 que numere 1 al 8 (esto si se puede sino me conformo con una numeración correlativa)
SI lo que deseas es que numere los envíos del 1 al 9, por ejemplo, eso es posible siempre y cuando exista un valor por el que hacer la verificación. Por ejemplo lo que se puede hacer con el detalle de la factura, ya que existe un numero de factura identificable.
Pero eso casos se construyen programáticamente o bien por stored procedures.
En tu caso, al pretender hacer un TRIGGER, no puedes usar otros valores que los de la propia tabla y el propio registro que dispara el TRIGGER mismo. No se pueden pasar otros datos y por tanto dependerá de lo que tengas en ese registro.

Así, pues: Es posible hacer un trigger que (te recomiendo) INSERTE un registro en una tabla de envíos, para un pedido dado, y que estos se numeren incrementalmente. Lo que no podrás hacer es detener las inserciones si superas el numero, sin provocar un error que deberá devolver un mensaje que tu aplicación entienda, y en consecuencia deshaga el UPDATE que lo disparó...
¿Esto ultimo lo tienes claro?
Para tu meta, tendrás que trabajar con transacciones.
La idea base sería mas o menos esta:

Código MySQL:
Ver original
  1. CREATE TRIGGER numerar
  2. AFTER UPDATE ON envios
  3.   DECLARE numEnv INT;  
  4.   SET numEnv = (SELECT COUNT(*) FROM pedidos WHERE idenvio = NEW.idenvio AND `status` = 'Enviado');
  5.   IF numEnv < 9 THEN
  6.       SET NEW.idal = CONCAT('T', (numEnv+1));
  7.   ELSE
  8.      SIGNAL SQLSTATE VALUE '99999'
  9.      SET MESSAGE_TEXT = 'Cantidad de envios excedidos';
  10.   END IF;

El ELSE se supone que disparará un error de ejecución si superas los nueve registros, por ejemplo.

Como podrás ver comparando tu codigo con el mío es que te has olvidado (o no has leido con cuidado el manual), las pseudovariables NEW y OLD, la seguda de las cuales no usamos en este caso, y tampoco te has fijado en cerrar el BEGIN. El END NO ESTABA.
__________________
¿A quién le enseñan sus aciertos?, si yo aprendo de mis errores constantemente...
"El problema es la interfase silla-teclado." (Gillermo Luque)
  #13 (permalink)  
Antiguo 17/06/2016, 08:59
 
Fecha de Ingreso: abril-2016
Mensajes: 90
Antigüedad: 8 años, 8 meses
Puntos: 1
Respuesta: disparador duda

Buenas, creo que me explico muy mal, esta es la estructura , lo que necesito es numerar los pedido enviados por centro,
Ejemplo 1 fecha pedido 13/05/2016 enviado el 16/05/2016 del centro T2 como es el primero coge el valor 001.
Ejemplo 2 fecha pedido 12/05/2016 y 13/05/2016 Enviado el 15/05/2016 del centro T6 como ambas líneas son las primeras su numero es 001

Siguiendo este esquema los pedido con fecha de envio 16/05/2016 del centro T6 con status Enviado tendrían que coger valor 002.

De esta misma forma el siguiente pedido con status Enviado del centro T2 (sea de una o varias líneas debería coger el valor idal 003.

Cita:
fechaEnvio | fechapedido | centro | status | idal
16/05/2016 | 13/05/2016 | T2 | Enviado |001
----------------------------------------------------------
___________ |13/05/2016 |T2 | |
----------------------------------------------------------
15/05/2016 |12/05/2016 | T6 | Enviado | 001
----------------------------------------------------------
15/05/2016 | 13/05/2016 | T6 | Enviado | 001
----------------------------------------------------------
16/05/2016 | 11/05/2016 | T6 | Enviado |
----------------------------------------------------------
17/05/2016 | 13/05/2016 | T2 | Enviado | 002
-----------------------------------------------------------
16/05/2016 | 12/05/2016 | T6 | Enviado |
-----------------------------------------------------------
Espero haberme explicado un poco mejor.

Gracias por ser tan paciente
  #14 (permalink)  
Antiguo 20/06/2016, 05:41
 
Fecha de Ingreso: abril-2016
Mensajes: 90
Antigüedad: 8 años, 8 meses
Puntos: 1
Respuesta: disparador duda

Buenas, he encontrado este ejemplo que posteaste en 2009 y creo que se adecua bastante a lo que busco, sin embargo me da error al intentar añadirlo

En este ejemplo solo necesitaría saber como añadirle que la numeración la haga según el centro

El error que me da solo poniendo mis datos es:
#1235 - This version of MySQL doesn't yet support 'multiple triggers with the same action time and event for one table'
Código MySQL:
Ver original
  1. DELIMITER $$
  2. CREATE TRIGGER SET_ITEMFACTURA BEFORE INSERT
  3. ON FACTURA_DETALLE
  4.     IF(SELECT MAX(SUBITEM) FROM FACTURA_DETALLE WHERE FACTURA_ID=NEW.FACTURA_ID) IS NULL THEN
  5.         SET NEW.SUBITEM = 1;
  6.     ELSE
  7.       SET NEW.SUBITEM = (SELECT MAX(SUBITEM) FROM FACTURA_DETALLE WHERE FACTURA_ID=NEW.FACTURA_ID) + 1;
  8.     END IF;
  9. END$$
  10.  
  11. DELIMITER ;

Última edición por gnzsoloyo; 21/06/2016 a las 08:38
  #15 (permalink)  
Antiguo 20/06/2016, 11:50
Avatar de gnzsoloyo
Moderador criollo
 
Fecha de Ingreso: noviembre-2007
Ubicación: Actualmente en Buenos Aires (el enemigo ancestral)
Mensajes: 23.324
Antigüedad: 17 años
Puntos: 2658
Respuesta: disparador duda

Tienes que dropear el TRIGGER anterior antes de poner el nuevo.
MySQL no admite múltiples TRIGGERS en la misma tabla para el mismo evento.
__________________
¿A quién le enseñan sus aciertos?, si yo aprendo de mis errores constantemente...
"El problema es la interfase silla-teclado." (Gillermo Luque)
  #16 (permalink)  
Antiguo 20/06/2016, 12:18
 
Fecha de Ingreso: abril-2016
Mensajes: 90
Antigüedad: 8 años, 8 meses
Puntos: 1
Respuesta: disparador duda

Gracias, ya lo había averiguado, ahora estoy intentando ajustarlo a lo que necesito

Etiquetas: disparador, select, tabla
Atención: Estás leyendo un tema que no tiene actividad desde hace más de 6 MESES, te recomendamos abrir un Nuevo tema en lugar de responder al actual.
Respuesta




La zona horaria es GMT -6. Ahora son las 18:59.