Ya comenté hace tiempo cómo exportar un stored procedure al servidor dónde tienes contratado el hosting, requisitos: acceso directo al servidor MySQL. Pero qué pasa si has seguido mi consejo sobre Hosting Profesional Gratuito -o si de cualquier otro modo- has acabado en 1and1 -u otro Hosting Provider- dónde no se puede hacer semejante cosa …
Aunque «DELIMITER» es una palabra reservada a partir de MySQL 5.0, si utilizas PhpMyAdmin y tratas de ejecutar en la pestaña de «SQL»
DELIMITER $$ DROP FUNCTION IF EXISTS `newsletters`.`f_inGroup` $$ CREATE FUNCTION `f_inGroup`(nUser int, nGroup int) RETURNS tinyint(4) BEGIN DECLARE yon TINYINT; SELECT count(*) INTO @yon FROM t_usersgroups WHERE idUser=nUser AND idGroup=nGroup; RETURN @yon; END $$ DELIMITER ;
Te dirá que tienes un error de sintaxis en «DELIMITER»
Así que me he tenido que construir (no prometí que fuera muy usable) un pequeño fichero php:
$sql = ""; $sql .= "DROP FUNCTION IF EXISTS f_inGroup"; mysql_query($sql, $dbLink) or die("Error :: ".mysql_error($dbLink)." :: ".$sql); $sql = "CREATE FUNCTION f_inGroup (nUser int, nGroup int) RETURNS tinyint(4) BEGIN n"; $sql .= "DECLARE yon TINYINT; n"; $sql .= "SELECT count(*) INTO @yon FROM t_usersgroups WHERE idUser=nUser AND idGroup=nGroup; n"; $sql .= "RETURN @yon; n"; $sql .= "END n"; mysql_query($sql, $dbLink) or die($sql);
¿Porqué funciona mejor esta solución? o simplemente ¿Porqué funciona? o ¿Qué te hizo pensar que funcionaría? (en este caso, gracias por no considerarme un desesperado que prueba cualquier cosa).
La necesidad de usar DELIMITER surge de separar lo que son consultas puntuales, de conjuntos de consultas. En verdad, la declaración de un Stored Procedure o una Function o un Trigger podría detectarse al encontrar un END que cierre el BEGIN con el cual empezó todo, pero como es costumbre en MySQL que exista un caracter que indique al parser «hasta aquí» pues se encontraron con este problemita, y se debió proveer una manera de establecer un segundo caracter (o conjunto de carácteres) que dijeran «punto final».
Bueno, una vez entendido esto, esperas pacientemente a que una vocecita interna te diga «cuando haces un mysql_query no necesitas poner el punto y coma final, porque se entiende que cada ejecución de esa función es un comando por si mismo» entonces se enciende la luz de idea, ese momento mágico en que el sislogismo se completa sin ser conscientes del razonamiento intermedio, bien por el subconsciente, e imaginas cómo todo ha subido un nivel en una jerarquía imaginaria, y te dices «si no necesito un punto y coma para separar los comandos, ya no necesito un DELIMITER que indique el final del comando, y puedo usar el punto-y-coma tan tranquilamente para separar las instrucciones internas del Stored Procedure, Function, o Trigger. Pruebas, y cuela.
Y mientras escribes en tu blog, porqué el día parece más soleado, te das cuenta que seguramente hubiera pasado lo mismo de haber puesto el contenido de $sql en la pestaña de SQL del PhpMyAdmin … porque seguramente lo que hará es recuperar el contenido del TextArea y lanzarlo con un mysql_query … pero esa experimentación la haré otro día, para que no se pierda la curiosidad.