elhacker.net cabecera Bienvenido(a), Visitante. Por favor Ingresar o Registrarse
¿Perdiste tu email de activación?.

 

 


Tema destacado: Los 10 CVE más críticos (peligrosos) de 2020


+  Foro de elhacker.net
|-+  Programación
| |-+  Desarrollo Web
| | |-+  Bases de Datos (Moderador: Carloswaldo)
| | | |-+  Trigger sencillo MySQL
0 Usuarios y 1 Visitante están viendo este tema.
Páginas: [1] 2 Ir Abajo Respuesta Imprimir
Autor Tema: Trigger sencillo MySQL  (Leído 7,924 veces)
Baal_30

Desconectado Desconectado

Mensajes: 248



Ver Perfil
Trigger sencillo MySQL
« en: 20 Junio 2015, 00:21 am »

Muy buenas, tengo una tabla que se llama "personaje" que tiene una columna que es "reino" y es un INT, también tengo una tabla que se llama "reino" y tiene una columna que se llama "id" y es un INT también.

Estoy probando a crear este trigger pero me da error en la linea 7 dice (donde la sentencia del DELETE) :/

Código
  1. CREATE TRIGGER borrarPersonaje
  2. BEFORE DELETE
  3. ON personaje
  4. FOR EACH ROW
  5. BEGIN
  6.  
  7. DELETE FROM reino WHERE id = OLD.reino;
  8.  
  9. END;

¿Que estoy haciendo mal?

Un saludo.


En línea

«La suerte es el cuidado de los detalles». -Winston Churchill
fran800m

Desconectado Desconectado

Mensajes: 204



Ver Perfil
Re: Trigger sencillo MySQL
« Respuesta #1 en: 20 Junio 2015, 14:54 pm »

Hace siglos que no hago trigger y en MySql ni siquiera lo he hecho en la vida, ¿qué error te da?

Un saludo,


En línea

Baal_30

Desconectado Desconectado

Mensajes: 248



Ver Perfil
Re: Trigger sencillo MySQL
« Respuesta #2 en: 20 Junio 2015, 17:27 pm »

Me dice : "You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '' at line 7"

Y nada más :/
En línea

«La suerte es el cuidado de los detalles». -Winston Churchill
fran800m

Desconectado Desconectado

Mensajes: 204



Ver Perfil
Re: Trigger sencillo MySQL
« Respuesta #3 en: 20 Junio 2015, 20:54 pm »

Prueba con
Código:
delimiter //
CREATE TRIGGER borrarPersonaje
    BEFORE DELETE
    ON personaje
    FOR EACH ROW
    BEGIN
     
    DELETE FROM reino WHERE id = OLD.reino;
     
    END;//
delimiter ;
   
En línea

Baal_30

Desconectado Desconectado

Mensajes: 248



Ver Perfil
Re: Trigger sencillo MySQL
« Respuesta #4 en: 25 Junio 2015, 17:26 pm »

He probado y se me queda bloqueado el phpmyadmin con el cartelito de "cargando..." :/
En línea

«La suerte es el cuidado de los detalles». -Winston Churchill
WHK
Moderador Global
***
Desconectado Desconectado

Mensajes: 6.605


Sin conocimiento no hay espíritu


Ver Perfil WWW
Re: Trigger sencillo MySQL
« Respuesta #5 en: 27 Junio 2015, 20:06 pm »

Debes tener un conflicto en tu tabla, tendriamos que ver la estructura completa de tu base de datos para saber porque se está bloqueando. Por ejemplo talves tienes una acción on delete que hace una llamada recursiva infinita, me ha pasado varias veces y pars solucionarlo debo crear tablas intermedias o eliminar una acción.
En línea

Baal_30

Desconectado Desconectado

Mensajes: 248



Ver Perfil
Re: Trigger sencillo MySQL
« Respuesta #6 en: 27 Junio 2015, 22:47 pm »

No puse ningún ON DELETE ni ON UPDATE, estarán por defecto todos supongo :/
En línea

«La suerte es el cuidado de los detalles». -Winston Churchill
WHK
Moderador Global
***
Desconectado Desconectado

Mensajes: 6.605


Sin conocimiento no hay espíritu


Ver Perfil WWW
Re: Trigger sencillo MySQL
« Respuesta #7 en: 27 Junio 2015, 23:11 pm »

Si es una base de datos relacional con foreign keys entonces vas a tener problemas si no estableces una acción ya que si tienes una tabla de relaciones entre una tabla A y tabla B cuando uno de estos sea eliminado o modificado vas a tener un valor nulo o corrupto en la tabla de relaciones ya que estará apuntando a un registro que ya no existe.

Eso de eliminar una fila cuando un registro de otra tabla es eliminado no se hace a traves de triggers sino con tablas relacinales y foreign keys.

Dale un vistazo a esta base de datos:
http://foro.elhacker.net/bases_de_datos/ayuda_amigo_necesito_crear_una_base_de_datos-t437701.0.html;msg2023594#msg2023594

Todos los puntos de color rojos son llaves foraneas que tienen como acción "cascade" lo cual indica que cuando se elimina o se modifica este tambien debe eliminarse o actualizarse desde la tabla de relaciones.

En algunos casos cuando tienes una tabla con una columna que apunta a otra tabla (de uno a uno) entonces la acción es set null para que el valor se vuelva nulo y no te elimine todo el registro:

Código:
CREATE TABLE IF NOT EXISTS `usuarios_telefonos` (
  `usuario_id` INT(11) NOT NULL AUTO_INCREMENT,
  `codigo_pais` INT(11) NOT NULL,
  `codigo_ciudad` INT(11) NOT NULL,
  `numero` INT(11) NOT NULL,
  `es_fijo` TINYINT(1) NOT NULL DEFAULT 0,
  PRIMARY KEY (`usuario_id`),
  CONSTRAINT `fk_usuarios_telefonos_usuarios1`
    FOREIGN KEY (`usuario_id`)
    REFERENCES `usuarios` (`id`)
    ON DELETE CASCADE
    ON UPDATE CASCADE)
ENGINE = InnoDB
DEFAULT CHARACTER SET = utf8
COLLATE = utf8_general_ci;

« Última modificación: 27 Junio 2015, 23:13 pm por WHK » En línea

Baal_30

Desconectado Desconectado

Mensajes: 248



Ver Perfil
Re: Trigger sencillo MySQL
« Respuesta #8 en: 29 Junio 2015, 13:57 pm »

ummm muchas gracias por la explicación ¡! Es que creía que si no ponías nada en el ON DELETE se ponía por defecto CASCADE, pero no es así por lo que se ve ¿verdad?

Es aconsejable poner SIEMPRE el ON DELETE y ON CASCADE pues...¿no?

¿Y está mal hacer lo que busco con un trigger? ¿Siempre mejor con tablas? ¿Y borrando el registro de la tabla esa directamente y au?
En línea

«La suerte es el cuidado de los detalles». -Winston Churchill
WHK
Moderador Global
***
Desconectado Desconectado

Mensajes: 6.605


Sin conocimiento no hay espíritu


Ver Perfil WWW
Re: Trigger sencillo MySQL
« Respuesta #9 en: 29 Junio 2015, 15:41 pm »

Pues MySQL con el motor innodb están diseñados para ese tipo de trabajo de manera automática y no, no siempre se debe poner on cascade, debes tomar cada relación y pensar bien que debería suceder cuando se elimina o actualiza un registro, la mayoría de las veces son on cascade, eso si, pero no siempre es así, hay veces que necesitas establecer a null, yo en lo personal nunca he utilizado el restringir el valor o la fila, siempre uso cascade o set null dependiendo del caso, en el caso de una tabla relacional de muchos a muchos si es necesario hacerlo con cascade y no necesitarás triggers, de hecho de mis años programando jamás he necesitado utilizar triggers o funciones procedure, de hecho intento jamás usarlos ya que dejo ese trabajo de calculo al lenguaje de programación del lado del código y no de la base de datos ya que cuando necesitas hacer un flujo de una aplicación, documentarla y llevar un cierto orden no puedes dejar toda la lógica desparramada entre la base de datos y el código, para mi la base de datos es base de datos y el calculo de recoger y buscar datos se lo dejo al código y libero la carga del servidor (útil cuando trabajas con separación de capas).

Mira esto:

Código
  1. -- MySQL Workbench Synchronization
  2. -- Generated: 2015-06-29 10:30
  3. -- Model: New Model
  4. -- Version: 1.0
  5. -- Project: Name of the project
  6. -- Author: WHK
  7.  
  8. SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0;
  9. SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0;
  10. SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='TRADITIONAL,ALLOW_INVALID_DATES';
  11.  
  12. CREATE TABLE IF NOT EXISTS `blank`.`personaje` (
  13.  `id` INT(11) NOT NULL AUTO_INCREMENT,
  14.  `nombre` VARCHAR(256) NOT NULL,
  15.  `reino_id` INT(11) NULL DEFAULT NULL,
  16.  PRIMARY KEY (`id`),
  17.  INDEX `fk_personaje_reinos_idx` (`reino_id` ASC),
  18.  CONSTRAINT `fk_personaje_reinos`
  19.    FOREIGN KEY (`reino_id`)
  20.    REFERENCES `blank`.`reinos` (`id`)
  21.    ON DELETE SET NULL
  22.    ON UPDATE CASCADE)
  23. ENGINE = InnoDB
  24. DEFAULT CHARACTER SET = utf8
  25. COLLATE = utf8_general_ci;
  26.  
  27. CREATE TABLE IF NOT EXISTS `blank`.`reinos` (
  28.  `id` INT(11) NOT NULL AUTO_INCREMENT,
  29.  `nombre` VARCHAR(256) NOT NULL,
  30.  PRIMARY KEY (`id`))
  31. ENGINE = InnoDB
  32. DEFAULT CHARACTER SET = utf8
  33. COLLATE = utf8_general_ci;
  34.  
  35.  
  36. SET SQL_MODE=@OLD_SQL_MODE;
  37. SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS;
  38. SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS;
  39.  

En esta base de datos tienes personaje y reinos y la tabla de personajes tiene una columna con el id de reino, esto quiere decir que el personaje va a pertenecer a un solo reino o ninguno, por este motivo el valor por defecto es null, ahora, este valor tiene una acción de cascade cuando se actualiza el registro o set null cuando se elimina... como funciona esto?:

Cuando se actualiza el registro del reino entonces se actualiza tambien el valor en la fila del personaje, pero que pasa si eliminas el reino? si le pones cascade se va a eliminar el personaje, por eso lo estableces a null, ahora, si necesitas que el personaje siempre tenga un reino entonces le das la opcioon de bloqueo y restringes la fila, de esta manera no podra usarse el personaje hasta que manualmente le asignes un nuevo reino y no tendras problemas en la selección o actualización de registros.

Ahora, digamos que necesitas que el personaje pueda estar en mas de un reino asociado:

Código
  1. -- MySQL Workbench Synchronization
  2. -- Generated: 2015-06-29 10:35
  3. -- Model: New Model
  4. -- Version: 1.0
  5. -- Project: Name of the project
  6. -- Author: WHK
  7.  
  8. SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0;
  9. SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0;
  10. SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='TRADITIONAL,ALLOW_INVALID_DATES';
  11.  
  12. CREATE TABLE IF NOT EXISTS `blank`.`personaje` (
  13.  `id` INT(11) NOT NULL AUTO_INCREMENT,
  14.  `nombre` VARCHAR(256) NOT NULL,
  15.  PRIMARY KEY (`id`))
  16. ENGINE = InnoDB
  17. DEFAULT CHARACTER SET = utf8
  18. COLLATE = utf8_general_ci;
  19.  
  20. CREATE TABLE IF NOT EXISTS `blank`.`reinos` (
  21.  `id` INT(11) NOT NULL AUTO_INCREMENT,
  22.  `nombre` VARCHAR(256) NOT NULL,
  23.  PRIMARY KEY (`id`))
  24. ENGINE = InnoDB
  25. DEFAULT CHARACTER SET = utf8
  26. COLLATE = utf8_general_ci;
  27.  
  28. CREATE TABLE IF NOT EXISTS `blank`.`personajes_reinos_relacion` (
  29.  `personaje_id` INT(11) NOT NULL,
  30.  `reino_id` INT(11) NOT NULL,
  31.  PRIMARY KEY (`personaje_id`, `reino_id`),
  32.  INDEX `fk_personajes_reinos_relacion_reinos1_idx` (`reino_id` ASC),
  33.  CONSTRAINT `fk_personajes_reinos_relacion_personaje`
  34.    FOREIGN KEY (`personaje_id`)
  35.    REFERENCES `blank`.`personaje` (`id`)
  36.    ON DELETE CASCADE
  37.    ON UPDATE CASCADE,
  38.  CONSTRAINT `fk_personajes_reinos_relacion_reinos1`
  39.    FOREIGN KEY (`reino_id`)
  40.    REFERENCES `blank`.`reinos` (`id`)
  41.    ON DELETE CASCADE
  42.    ON UPDATE CASCADE)
  43. ENGINE = InnoDB
  44. DEFAULT CHARACTER SET = utf8
  45. COLLATE = utf8_general_ci;
  46.  
  47.  
  48. SET SQL_MODE=@OLD_SQL_MODE;
  49. SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS;
  50. SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS;
  51.  

En este caso hay una tabla intermedia de muchos a muchos donde un personaje puede estar asociado a mas de un mundo, ahora, si te fijas ambas columnas de esta tablas son llaves, esto quiere decir que no se podrán repetir los mundos con los personajes, esto quiere decir que si hay dos reinos entonces un personaje no podrá tener mas de dos reinos y si intentas asociar un reino por segunda ves la base de datos te arrojará un error diciendo que el registro está duplicado. Esto es súper útil si deseas mantener la integridad de datos de tu aplicación ya que si permites duplicidades vas a tener problemas muy serios al momento de manejar tus datos, esto te restringe en parte a diseñar una buena aplicación.

Si te fijas, en este ejemplo ambas funciones son cascade en ambas columnas ya que si eliminas un personaje o eliminas un reino entonces la relación desaparece, si eliminas un reino el personaje ya no estará asociado a el y eso es lo normal que pase y no que quede un registro fantasma que te diga que pertenece a un reino que no existe.

Bueno.... todo eso lo hace innodb de manera automática e innodb viene integrado por defecto con mysql.

Saludos.
En línea

Páginas: [1] 2 Ir Arriba Respuesta Imprimir 

Ir a:  

Mensajes similares
Asunto Iniciado por Respuestas Vistas Último mensaje
[Solucionado] Pregunta Trigger MySql
Bases de Datos
raul_samp 0 2,602 Último mensaje 27 Marzo 2012, 17:09 pm
por raul_samp
Duda con trigger en MySQL (after update y after insert)
Bases de Datos
WHK 1 5,763 Último mensaje 4 Febrero 2014, 00:27 am
por Toxico
[CUAL ES EL ERROR] Crear variables en trigger MYSQL [RESUELTO]
Bases de Datos
LaThortilla (Effort) 3 4,399 Último mensaje 20 Febrero 2015, 18:21 pm
por LaThortilla (Effort)
Declaracion de variables en trigger mysql
Bases de Datos
d91 1 12,972 Último mensaje 18 Enero 2017, 13:19 pm
por d91
Trigger complejos MySQL
Bases de Datos
rubcr 9 5,609 Último mensaje 5 Junio 2020, 21:24 pm
por K-YreX
WAP2 - Aviso Legal - Powered by SMF 1.1.21 | SMF © 2006-2008, Simple Machines