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

Quiero crear un trigger que me formatte una cadena de caracteres antes de insertarla

Estas en el tema de Quiero crear un trigger que me formatte una cadena de caracteres antes de insertarla en el foro de Mysql en Foros del Web. Hola amig@s. Mi problema es el siguiente; Resulta que en un formulario de registro recojo una cadena de caracteres a modo de fecha en el ...
  #1 (permalink)  
Antiguo 08/12/2009, 09:22
Avatar de aniMAYtions  
Fecha de Ingreso: diciembre-2007
Ubicación: Granada
Mensajes: 519
Antigüedad: 16 años, 4 meses
Puntos: 2
Quiero crear un trigger que me formatte una cadena de caracteres antes de insertarla

Hola amig@s.

Mi problema es el siguiente; Resulta que en un formulario de registro recojo una cadena de caracteres a modo de fecha en el formato dd/mm/aaaa. Por diversas razones, la conversión de la cadena debo hacerla con un trigger en mi base de datos mysql. Quiere decir, un trigger que me cambie el formato de la fecha a aaaa-mm-dd antes de ser insertada, ia que si intento insertar esta cadena en mi campo date me aparece como 0000-00-00 directamente.
Por el momento he intentado crear el trigger de la siguiente manera:
Código:
CREATE TRIGGER tr_formato_fecha  BEFORE INSERT ON emp_users
BEGIN
DECLARE @anio char(4),
 @mes char(2),
 @dia char(2);
SET @anio = MID(NEW.fecha_nacimiento, 7, 4);
SET @mes = MID(NEW.fecha_nacimiento, 4, 2);
SET @dia = MID(NEW.fecha_nacimiento, 1, 2);
SET NEW.fecha_nacimiento = concat(@anio, "-",@mes,"-","dia");
END;
Lo he hecho con el DECLARE y sin él también, pero en cualquier caso Mysql sigue dándome error, el 1064.

Podeis decirme qué estoy haciendo mal??

Gracias!!
  #2 (permalink)  
Antiguo 08/12/2009, 10:30
Avatar de gnzsoloyo
Moderador criollo
 
Fecha de Ingreso: noviembre-2007
Ubicación: Actualmente en Buenos Aires (el enemigo ancestral)
Mensajes: 23.324
Antigüedad: 16 años, 4 meses
Puntos: 2658
Respuesta: Quiero crear un trigger que me formatte una cadena de caracteres antes de

Sería bueno que nos aclararas un poco acerca de las "diversas razones", porque en realidad el problema es muchísimo más sencillo de resolver desde la aplicación que con un trigger, ya que el trigger comienza a funcionar desde el mismo momento en que se dispara, pero cierto nivel de validaciones tienen que ver con la creación de NEW como registro entrante, así que el error de formato puede saltar antes que el trigger comience.

Te cuento que si trabajas con .Net, eso se resuelve usando sentencias con parámetros, si usas PHP, se puede resolver con createFromFormat o date_format, por ejemplo.
En cualquier caso sería una mejor solución que usar un trigger. Incluso, cuando no pudieras usarlas, si en la sentencia usas en esos casos STR_TO_DATE(), suplirías también el problema, sin necesidad de un trigger.

En definitiva, existen muchas soluciones mucho más efectivas y prácticas que un trigger para tu problema.

En cuanto al error de sintaxis, para otras ocasiones sería mejor que postearas (copiandolo) el mensaje completo de error, ya que sirve de guía.

En tu caso la cosa puede venir por varios lados:
1) Las variables de una rutina almacenada se pueden declarar en la misma línea si y sólo si son del mismo tipo y tamaño, con una sola declaración por cada uno de los tipos.
2) Las variables de usuario que comienzan con "@" no se declaran ni son locales. Son globales por sesión de usuario, por lo que deben ser inicializadas y luego usadas, pero no mueren al terminar la rutina ni aún creándolas en ella.
3) Toda declaración de un TRIGGER lleva las cláusulas FOR EACH ROW, que en tu caso faltaban.
4) Las comillas (") encierran nombres de bases, tablas y campos. Si quieres encerrar cadenas de texto, usa apóstrofes (').

El código podría quedar:
Código sql:
Ver original
  1. CREATE TRIGGER tr_formato_fecha  BEFORE INSERT ON emp_users FOR EACH ROW
  2. BEGIN
  3.     DECLARE anio CHAR(4);
  4.     DECLARE mes, dia CHAR(2);
  5.     SET anio = MID(NEW.fecha_nacimiento, 7, 4);
  6.     SET mes = MID(NEW.fecha_nacimiento, 4, 2);
  7.     SET dia = MID(NEW.fecha_nacimiento, 1, 2);
  8.     SET NEW.fecha_nacimiento = CONCAT(anio, '-', mes, '-', dia);
  9. END;

De todos modos, como ya te dije, sería más sencillo usar:
Código SQL:
Ver original
  1. INSERT INTO emp_users(fecha_nacimiento)
  2. VALUES(STR_TO_DATE(fechadenacimiento, '%d/%m/%Y %H'));
Mira este ejemplo:
Código SQL:
Ver original
  1. mysql> SELECT STR_TO_DATE('23/01/2003 13:45:08', '%d/%m/%Y %H');
  2. +---------------------------------------------------+
  3. | STR_TO_DATE('23/01/2003 13:45:08', '%d/%m/%Y %H') |
  4. +---------------------------------------------------+
  5. | 2003-01-23 13:00:00                               |
  6. +---------------------------------------------------+
  7. 1 ROW IN SET, 1 warning (0.00 sec)
La única condición sine qua non, es que el separador usado en la fecha tiene que ser el mismo que se indica en la función, o de lo contrario devolverá NULL:
Código sql:
Ver original
  1. mysql> SELECT STR_TO_DATE('23/01/2003 13:45:08', '%d-%m-%Y %H');
  2. +---------------------------------------------------+
  3. | STR_TO_DATE('23/01/2003 13:45:08', '%d-%m-%Y %H') |
  4. +---------------------------------------------------+
  5. | NULL                                              |
  6. +---------------------------------------------------+
  7. 1 ROW IN SET, 1 warning (0.00 sec)
__________________
¿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 08/12/2009, 10:56
Avatar de aniMAYtions  
Fecha de Ingreso: diciembre-2007
Ubicación: Granada
Mensajes: 519
Antigüedad: 16 años, 4 meses
Puntos: 2
Respuesta: Quiero crear un trigger que me formatte una cadena de caracteres antes de

Cita:
Iniciado por gnzsoloyo Ver Mensaje
Sería bueno que nos aclararas un poco acerca de las "diversas razones", porque en realidad el problema es muchísimo más sencillo de resolver desde la aplicación que con un trigger
Gracias por tu respuesta gnzsoloyo. Te aclaro en un momento las "diversas razones".
La aplicación en la que trabajao la estoy creando bajo el CMS Joomla. Y este formulario corresponde a uno de los componentes que trae el gestor. En el apartado correspondiente de este foro ia he preguntado cómo puedo hacerlo con código php, pues el componente se subdivide en miles de apartados con clases y funciones que no me están facilitando encontrar la solución fácil al problema, pero al parecer nadie tiene una respuesta.
Necesito terminar ésto lo más pronto posible, pues es una pequeña parte de un todo que no estará completo hasta que consiga solucionarlo.
Entonces, después de darle muchas vueltas a la cabeza he pensado que otra forma de hacerlo sería con un trigger que me formatease la cadena antes de ser insertada y así poder ser reconocida como date por mysql.
Otra opción sería poner el campo directamente como char, pero tú mismo me enseñaste en otro post que eso es una cutrada, y más aún si luego tengo que calcular la edad del usuario.

Te vuelvo a agradecer tu respuesta y voy a probar enseguida el código que me has posteado. Pero aunque funcionase no te preocupes, si me responden al otro post para hacerlo con código php eliminaré el trigger y lo haré de la otra forma.

Un saludo!!

Ah, por cierto, en el error que me muestra phpMyAdmin sólo dice
Error
consulta SQL:
mi consulta...
MySQL ha dicho:
#1064 -

Ya lo he probado y resulta que no... verás, este es el error que me da.

Y esta la consulta completa
Código:
 CREATE TRIGGER tr_formato_fecha  BEFORE INSERT ON emp_users FOR EACH ROW
      BEGIN
          DECLARE anio char(4);
          DECLARE mes, dia char(2);
          SET anio = MID(NEW.fecha_nacimiento, 7, 4);
          SET mes = MID(NEW.fecha_nacimiento, 4, 2);
          SET dia = MID(NEW.fecha_nacimiento, 1, 2);
          SET NEW.fecha_nacimiento = CONCAT(anio, '-', mes, '-', dia);
      END;
Está copiada y pegada. :(

Última edición por aniMAYtions; 08/12/2009 a las 11:09 Razón: ya lo probé
  #4 (permalink)  
Antiguo 09/12/2009, 09:54
Avatar de aniMAYtions  
Fecha de Ingreso: diciembre-2007
Ubicación: Granada
Mensajes: 519
Antigüedad: 16 años, 4 meses
Puntos: 2
Respuesta: Quiero crear un trigger que me formatte una cadena de caracteres antes de

Como os dije, compañer@s, necesitaba hacer ésto en un plazo de tiempo muy corto. Así que al final he optado por la vía rápida.
He dejado el campo como char de 10 para insertar la fecha en formato dd/mm/aaaa.
En esta parte de mi aplicación no tengo que hacer cálculos con ese dato, así podré tenerlo preparado a tiempo.
Más adelante, para la otra parte sí que me hará falta. Pero lo bueno es que esa otra parte no la controla joomla, así que podré hacerlo con código php.
De todas formas me he quedado con el gusanillo de no haber sacado ésto. Así que si teneis alguna idea, bienvenida sea.

Un saludo!!
  #5 (permalink)  
Antiguo 09/12/2009, 10:25
Avatar de gnzsoloyo
Moderador criollo
 
Fecha de Ingreso: noviembre-2007
Ubicación: Actualmente en Buenos Aires (el enemigo ancestral)
Mensajes: 23.324
Antigüedad: 16 años, 4 meses
Puntos: 2658
Respuesta: Quiero crear un trigger que me formatte una cadena de caracteres antes de

Tu error de sintaxis parece ser en tu caso un error de uso de PhpMyAdmin.
Cuando pones en la ventana de SQL un script de un Stored Procedure, se debe cambiar momentaneamente el caracter que MySQL usa como terminador de sentencias (el punto y coma), y suplantarlo por otro.
Cuando usas MySQL Query Browser esto es fácil porque hay una herramienta para crear el modulo de script que ya te incluye ese cambio y simplemente se lo corre como cualquier script.
En el caso de phpMyAdmin, debes usar un textbox que está en la parte inferior del formulario, y que dice "Delimitador (ver esta base para trays: phpMyAdmin Try)"
Allí puedes poner, por ejemplo, "$$", y en la última línea del script del trigger pon $$
__________________
¿A quién le enseñan sus aciertos?, si yo aprendo de mis errores constantemente...
"El problema es la interfase silla-teclado." (Gillermo Luque)
  #6 (permalink)  
Antiguo 09/12/2009, 12:42
Avatar de aniMAYtions  
Fecha de Ingreso: diciembre-2007
Ubicación: Granada
Mensajes: 519
Antigüedad: 16 años, 4 meses
Puntos: 2
Respuesta: Quiero crear un trigger que me formatte una cadena de caracteres antes de

Pues parece ser que mi phpMyAdmin tiene un grave error.
He visto el textbox que me dices en la página que has posteado. Pero cuál es mi sorpresa cuando en mi phpMyAdmin veo lo siguiente

Hay alguna forma de configurarlo para que me aparezca lo del delimitador??

Gracias de nuevo.
  #7 (permalink)  
Antiguo 09/12/2009, 13:35
Avatar de gnzsoloyo
Moderador criollo
 
Fecha de Ingreso: noviembre-2007
Ubicación: Actualmente en Buenos Aires (el enemigo ancestral)
Mensajes: 23.324
Antigüedad: 16 años, 4 meses
Puntos: 2658
Respuesta: Quiero crear un trigger que me formatte una cadena de caracteres antes de

¿Qué versión de phpMyAdmin estás usando?
__________________
¿A quién le enseñan sus aciertos?, si yo aprendo de mis errores constantemente...
"El problema es la interfase silla-teclado." (Gillermo Luque)
  #8 (permalink)  
Antiguo 10/12/2009, 01:14
Avatar de aniMAYtions  
Fecha de Ingreso: diciembre-2007
Ubicación: Granada
Mensajes: 519
Antigüedad: 16 años, 4 meses
Puntos: 2
Respuesta: Quiero crear un trigger que me formatte una cadena de caracteres antes de

La versión es la 2.8.0.4
  #9 (permalink)  
Antiguo 10/12/2009, 05:05
Avatar de gnzsoloyo
Moderador criollo
 
Fecha de Ingreso: noviembre-2007
Ubicación: Actualmente en Buenos Aires (el enemigo ancestral)
Mensajes: 23.324
Antigüedad: 16 años, 4 meses
Puntos: 2658
Respuesta: Quiero crear un trigger que me formatte una cadena de caracteres antes de

Es posible que la falta de ese textbox tenga algo que ver con eso, ya que la versión de gratuita de pruebas en la web cuyo link te puse en el post es 3.3.0-dev.
Para resolver el problema, deberías probar un formato que contenga las sentencias de cambio de delimitador:
Código sql:
Ver original
  1. DROP TRIGGER IF EXISTS tr_formato_fecha ;
  2. DELIMITER $$
  3.  
  4. CREATE TRIGGER tr_formato_fecha  BEFORE INSERT ON emp_users FOR EACH ROW
  5.       BEGIN
  6.           DECLARE anio CHAR(4);
  7.           DECLARE mes, dia CHAR(2);
  8.           SET anio = MID(NEW.fecha_nacimiento, 7, 4);
  9.           SET mes = MID(NEW.fecha_nacimiento, 4, 2);
  10.           SET dia = MID(NEW.fecha_nacimiento, 1, 2);
  11.           SET NEW.fecha_nacimiento = CONCAT(anio, '-', mes, '-', dia);
  12.       END$$
  13.  
  14. DELIMITER ;

Debe cambiarse el delimitador antes de procesar el script del trigger y luevo volverse al original, o de lo contrario el cambio permanecerá para todas las ejecuciones subsiguientes.
__________________
¿A quién le enseñan sus aciertos?, si yo aprendo de mis errores constantemente...
"El problema es la interfase silla-teclado." (Gillermo Luque)
  #10 (permalink)  
Antiguo 10/12/2009, 07:15
Avatar de aniMAYtions  
Fecha de Ingreso: diciembre-2007
Ubicación: Granada
Mensajes: 519
Antigüedad: 16 años, 4 meses
Puntos: 2
Respuesta: Quiero crear un trigger que me formatte una cadena de caracteres antes de

Veamos, si le pongo el drop trigger delante del delimitador no pasa de ahí.
Si pongo solo el delimitador también me da error.
Si pongo el delimitador, el drop trigger if exists acabado en $$ y luego cambio el delimitador a ; primero me pregunta si realmente quiero realizar la acción y cuando le digo que sí me vuelve a dar error.
Además, el drop trigger if exists me da error lo ponga como lo ponga, con o sin delimitador, con ; o con $$.

Será que la versión que tengo io del phpMyAdmin no admite triggers?? no creo, no es tan antigua leñe!!

Voy a ver qué encuentro googleando por aquí y si veo algo interesante lo posteo.

Gracias otra vez por tu respuesta gnzsoloyo y saludos.

Ah, por cierto, el error siempre es el 1064...
  #11 (permalink)  
Antiguo 10/12/2009, 07:20
Avatar de gnzsoloyo
Moderador criollo
 
Fecha de Ingreso: noviembre-2007
Ubicación: Actualmente en Buenos Aires (el enemigo ancestral)
Mensajes: 23.324
Antigüedad: 16 años, 4 meses
Puntos: 2658
Respuesta: Quiero crear un trigger que me formatte una cadena de caracteres antes de

Pregunta del millón: ¿Qué versión de MySQL tienes instalada y qué versión se usará finalmente?
Cita:
Será que la versión que tengo io del phpMyAdmin no admite triggers??
phpMyAdmin es sólo una interfase web para administrar el acceso a MySQL. No es una base de datos. El problema está en saber si la versión de MySQL es 4.x o 5.x, porque la 4.x no tiene TRIGGERS.

Cita:
Veamos, si le pongo el drop trigger delante del delimitador no pasa de ahí.
Si pongo solo el delimitador también me da error.
Si pongo el delimitador, el drop trigger if exists acabado en $$ y luego cambio el delimitador a ; primero me pregunta si realmente quiero realizar la acción y cuando le digo que sí me vuelve a dar error.
Eso sucede habitualmente cuando tienes en ese formulario un punto específico donde cambiar el delimitador de sentencias.
Fuera de lo que mostraste, ¿el formulario se extiende más abajo? Si es así ¿Qué hay allí?
¿Aparece algo 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)

Última edición por gnzsoloyo; 10/12/2009 a las 07:33
  #12 (permalink)  
Antiguo 10/12/2009, 07:30
Avatar de aniMAYtions  
Fecha de Ingreso: diciembre-2007
Ubicación: Granada
Mensajes: 519
Antigüedad: 16 años, 4 meses
Puntos: 2
Respuesta: Quiero crear un trigger que me formatte una cadena de caracteres antes de

Cita:
Iniciado por gnzsoloyo Ver Mensaje
phpMyAdmin es sólo una interfase web para administrar el acceso a MySQL. No es una base de datos. El problema está en saber si la versión de MySQL es 4.x o 5.x, porque la 4.x no tiene TRIGGERS.
Lo sé hij@, lo sé. Hacía mucho que no utilizaba Mysql como motor de mis aplicaciones, pero esas cosas nunca se olvidan...
La versión de Mysql es la 5.0.21.

Cita:
Iniciado por gnzsoloyo Ver Mensaje
¿el formulario se extiende más abajo?
Qué va, esa es la ventanita que te muestra cuando pinchas en la pestaña sql. Como mucho le sale al lado la ventanita con los campos si estás en una tabla en concreto de la base de datos.

Lo que io diga, todo un misterio.

Saludos y gracias de nuevo
  #13 (permalink)  
Antiguo 10/12/2009, 07:53
Avatar de gnzsoloyo
Moderador criollo
 
Fecha de Ingreso: noviembre-2007
Ubicación: Actualmente en Buenos Aires (el enemigo ancestral)
Mensajes: 23.324
Antigüedad: 16 años, 4 meses
Puntos: 2658
Respuesta: Quiero crear un trigger que me formatte una cadena de caracteres antes de

De acuerdo a este post del foro de MySQL.com, tu problema puede ser un bug en la versión de phpMyAdmin.
Considera seriamente actualizar a una versión más reciente. Con 2.10.3 o bien 2.11.0 alcanzaría.
__________________
¿A quién le enseñan sus aciertos?, si yo aprendo de mis errores constantemente...
"El problema es la interfase silla-teclado." (Gillermo Luque)
  #14 (permalink)  
Antiguo 10/12/2009, 08:07
Avatar de huesos52
Colaborador
 
Fecha de Ingreso: febrero-2009
Ubicación: Manizales - Colombia
Mensajes: 5.980
Antigüedad: 15 años, 2 meses
Puntos: 360
Respuesta: Quiero crear un trigger que me formatte una cadena de caracteres antes de

Con certeza el problema es la versión de phpmyadmin.

http://forums.mysql.com/read.php?99,...250#msg-167250

saludos
__________________
Without data, You are another person with an opinion.
W. Edwads Deming
  #15 (permalink)  
Antiguo 11/12/2009, 01:16
Avatar de aniMAYtions  
Fecha de Ingreso: diciembre-2007
Ubicación: Granada
Mensajes: 519
Antigüedad: 16 años, 4 meses
Puntos: 2
Respuesta: Quiero crear un trigger que me formatte una cadena de caracteres antes de

Gracias chic@s. Yo no soy la administradora de la red, pero se lo diré a la persona encargada de eso lo antes posible y cuando consiga que me salga os lo comunicaré.

Un saludo!!
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 02:10.