Ver Mensaje Individual
  #4 (permalink)  
Antiguo 22/05/2015, 05:36
Avatar de gnzsoloyo
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: Procedimiento con un resultado pasado como parámatreo

Bueno, tomé tu SP, lo copie y le di un formato un poco más claro, porque tal como estaba escrito, sin indentaciones, era imposible de entender a simple vista.
Te recomiendo codificar los SP de un modo estructurado, tal que te permita ver claramente lo que sucede.

La cosa es así:
Código MySQL:
Ver original
  1. delimiter $$
  2. DROP PROCEDURE IF EXISTS resultados$$
  3. CREATE PROCEDURE resultados(INOUT resultado CHAR(7))
  4.  
  5.     DECLARE tantos1 INTEGER;
  6.     DECLARE tantos2 INTEGER;
  7.     DECLARE result CHAR(1);
  8.  
  9.     IF LENGTH(resultado)=7 THEN
  10.         SET tantos1=SUBSTR(resultado,1,3);
  11.         SET tantos2=SUBSTR(resultado,5,7);
  12.     ELSEIF tantos1 > tantos2 THEN
  13.         SET result='1';
  14.     ELSEIF tantos2 > tantos1 THEN
  15.         SET result='2';
  16.     ELSEIF tantos1=tantos2 THEN
  17.             SET result='x';
  18.     ELSE
  19.         SELECT ('error') resultado;
  20.     END IF;
  21.     SELECT result resultado;
  22. END$$
  23.  
  24. DELIMITER ;
Con eso a la vista, el problema es harto evidente: Nunca entrará en ningún ELSEIF ni ELSE, porque al momento de iniciar el IF, el valor de ambas variables es CERO.
Le estás asignando el valor dentro del IF inicial, y todos los ELSEIF operan después.
Un ELSEIF devuelve TRUE y ejecuta su código si y sólo si el IF inicial devuelve FALSE, que no sería el caso. Solo sucedería si el CALL fuese algo como por ejemplo:

Código MySQL:
Ver original
  1. CALL resultados('088087');
Es decir, debería tener menos o más de 7 caracteres para ser FALSE y recién alli entraría en los ELSEIF.
Ahora bien, si pasara eso, el valor de tantos1 y tantos2 sería NULL, porque están declaradas pero no incializadas. Y en todo caso podrían tener valor cero, de poseer una condición de default.
Pero como no estás evaluando el NULL, y NULL no funciona con operadores lógicos comunes en MySQL, la consecuencia sería que saliese por ELSE, devolviendo la cadena "error". Si el valor por default de las variabls fuese cero, entonces podría salir con valor "X".
Pero son las unicas alternativas.

Yo veo dos cosas principales:
1) No entiendo por qué quieres usar una única variable de entrada, cuando siendo una comparación lo óptimo sería hacerlo con dos numéricas.
Código MySQL:
Ver original
  1. delimiter $$
  2. DROP PROCEDURE IF EXISTS resultados$$
  3. CREATE PROCEDURE resultados(IN valor1 INT, IN valor2 INT, OUT resultado CHAR(10))
  4.     IF valor1 > valor2  THEN
  5.         SET resultado = '1';
  6.     ELSEIF tantos2 < tantos1 THEN
  7.         SET resultado = '2';
  8.     ELSE
  9.             SET resultado = 'x';
  10.     END IF;
  11.     SELECT resultado;
  12. END$$
  13.  
  14. delimiter ;
  15.  
  16. CALL resultados(88, 087, result);

2) Estás complicando innecesariamente el script y anidando incorrectamente las validaciones, además de validar en un mismo IF cosas que no están relacionadas.
Esto sería lo tuyo, limpio:
Código MySQL:
Ver original
  1. delimiter $$
  2. DROP PROCEDURE IF EXISTS resultados$$
  3. CREATE PROCEDURE resultados(IN resultado CHAR(7))
  4.  
  5.     DECLARE tantos1 INTEGER;
  6.     DECLARE tantos2 INTEGER;
  7.     DECLARE result CHAR(7);
  8.     IF LENGTH(TRIM(resultado)) =7 THEN
  9.         SET tantos1=SUBSTR(resultado,1,3);
  10.         SET tantos2=SUBSTR(resultado,5,7);
  11.         IF tantos1 > tantos2 THEN
  12.             SET result='1';
  13.         ELSEIF tantos1 < tantos2 THEN
  14.             # No cambies la posicion de las variables, genera errores de comprension a primera vista
  15.             SET result='2';
  16.         ELSE
  17.             # Si tantos1 no es mayor ni menor a tantos2, sólo puede ser igual...
  18.             SET result='x';
  19.         END IF;
  20.     ELSE
  21.         # No tiene sentido evaluarlo dentro de las condiciones de igualdad.
  22.         # Es una condicion del parametro de entrada. No mezcles logicas incompatibles
  23.         SELECT ('error') resultado;
  24.     END IF;
  25.     # No tiene sentido usar variables de salida, ni tampoco
  26.     # dos salidas, si el SP sólo devolvera un unico resultado.
  27.     # alcanza con que luego en la aplciacion evalues la respuesta.
  28.     SELECT result resultado;
  29. END$$
  30.  
  31. DELIMITER ;

Una nota final: Los SP no se hacen para hacer procesos de este tipo, sino para procesos donde realizará consultas a la base de datos. En todo caso, si devolverá sólo una cadena de texto siempre, debería ser una stored function, y no un stored procedure.

Este ejercicio no tiene sentido en MySQL, es propio de programación en algún lenguaje y carece de utilidad en una base de datos. Si te lo dieron como ejercitación, está muy mal pensado.

Nota 2: Cambie los parametros a IN, porque si estás enviando una constante, entonces el resultado se pierde. Para que te funcione deberás invocar el SP en MYSQL, o bien deberás hacerlo por lenguaje de programación de la misma forma en que realizas una consulta a una tabla, ya que ese SP devolverá una tabla.
__________________
¿A quién le enseñan sus aciertos?, si yo aprendo de mis errores constantemente...
"El problema es la interfase silla-teclado." (Gillermo Luque)