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

retornar un valor desde un procedure

Estas en el tema de retornar un valor desde un procedure en el foro de Mysql en Foros del Web. Hola amigos, estoy intentando que tras ejecutar un procedure este me devuelva solo un dato. este es mi procedimiento: Código: CREATE DEFINER=`root`@`localhost` PROCEDURE `PA_Arribos`(xop int, ...
  #1 (permalink)  
Antiguo 25/11/2010, 08:37
Avatar de Copia  
Fecha de Ingreso: noviembre-2009
Mensajes: 309
Antigüedad: 14 años, 4 meses
Puntos: 4
retornar un valor desde un procedure

Hola amigos, estoy intentando que tras ejecutar un procedure este me devuelva solo un dato.
este es mi procedimiento:
Código:
CREATE DEFINER=`root`@`localhost` PROCEDURE `PA_Arribos`(xop int, xidEmpTransport int, xDireccion varchar(150), xnumVuelo int,

                                       xfechaLlegada date, xHoraLlegada time , xnumPersonas int, out xidArribo int)
BEGIN


declare xidArribo int; 

set xidArribo = (select max(idArribos)+1 from arribos);

 
 case xop

     when 1 then


          insert into arribos(idArribos, idEmpTransporte,Direccion,NumVuelo, FechaLlegada, HoraLlegada, NumPersonas)

          values(xidArribo, xidEmpTransport,xDireccion,xnumVuelo,xfechaLlegada, xHoraLlegada, xnumPersonas);
          

  end case;
            

END
quiero devolver xidArribo, porque es el id de la tabla a la que estoy insertando y necesito tener ese id para guardarlo en otra tabla, pero no lo puedo retornar.
¿Como hago para retornar ese valor?, ahora si yo trabajo con un
case xop
when 1 then
sentencia sql
return xidArribo
when 2 then

se puede devolver algun valor desde el case?? y terminar su ejecucion cuando encuentre el valor?
  #2 (permalink)  
Antiguo 25/11/2010, 08: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: 16 años, 4 meses
Puntos: 2658
Respuesta: retornar un valor desde un procedure

Todo es posible... La pregunta que surge es: ¿Sobre qué lenguaje de programación estás trabajando?

Pregunto esto porque un SP parametrizado devuelve el valor en el parámetro, pero para poder recuperarlo en la aplicación el lenguaje debe poder recuperar el parámetro y leer su valor.
Este tipo de cosas son muy sencillas de hacer en .Net, pero no son tan fáciles usando mysql_query(), de PHP, por ejemplo.
Fuera de eso el SP mejor programado quedaría:

Código MySQL:
Ver original
  1. CREATE PROCEDURE `PA_Arribos`(
  2.     IN xop INT,
  3.     IN xidEmpTransport INT,
  4.     IN xDireccion VARCHAR(150),
  5.     IN xnumVuelo INT,
  6.     IN xfechaLlegada DATE,
  7.     IN xHoraLlegada TIME,
  8.     IN xnumPersonas INT,
  9.     OUT xidArribo INT)
  10.     SET xidArribo = 0;
  11.     IF  xop = 1 THEN
  12.         INSERT INTO arribos(idArribos, idEmpTransporte,Direccion,NumVuelo, FechaLlegada, HoraLlegada, NumPersonas)
  13.         VALUES(xidArribo, xidEmpTransport,xDireccion,xnumVuelo,xfechaLlegada, xHoraLlegada, xnumPersonas);
  14.         SET xidArribo = LAST_ISERT_ID();
  15.     END IF;
Hay algunos tips:
1) No se deben declarar variables con el mismo nombre de las variables del prototipo.
2) CASE sin un ELSE puede darte un error si la variable toma un valor no contemplado en los WHEN.
3) Si sólo vas a tomar una opción, usar un CASE carece de sentido.
4) Si lo que quieres recuperar es un valor autogenerado, para eso existen funciones específicas.
__________________
¿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 25/11/2010, 09:00
Avatar de Copia  
Fecha de Ingreso: noviembre-2009
Mensajes: 309
Antigüedad: 14 años, 4 meses
Puntos: 4
Respuesta: retornar un valor desde un procedure

gracias por responder, si implemente el case fue porque tengo mas de un when, pasa que xop es la operacion que deseo realizar algo como : xop = 1 para insertar, xop = 2 para modificar, etc.. solo que lo deje ahi porque es donde estoy.

Ahora el lenguaje en el que lo implementare es en php.

y una ultima consulta, ¿es necesario ingresar los in al declarar la variable, porque sin ellos igual me lo acepta?
  #4 (permalink)  
Antiguo 25/11/2010, 09: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: retornar un valor desde un procedure

En PHP, hasta lo que sé, sólo podrías recuperar el valor poniendo una SELECT al final, de modo que te devuelva el valor de la variable en forma de tabla de un único registro.
Cita:
y una ultima consulta, ¿es necesario ingresar los in al declarar la variable, porque sin ellos igual me lo acepta?
Es una cuestión de práctica. Yo acostumbro a ser ortodoxo en la codificación para que luego me resulte más fácil leerla para modificarla o corregirla. Aparte de eso, todo parámetro cuya dirección no indicas es siempre IN.
__________________
¿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 25/11/2010, 09:31
Avatar de Copia  
Fecha de Ingreso: noviembre-2009
Mensajes: 309
Antigüedad: 14 años, 4 meses
Puntos: 4
Respuesta: retornar un valor desde un procedure

no estoy seguro si se pueda devolver un dato desde un when del case, pero modifique un tanto mi codigo, y el error esta en el return porque presumo que es incorrecto.
Código:
-- --------------------------------------------------------------------------------
-- Routine DDL
-- --------------------------------------------------------------------------------
DELIMITER $$

CREATE DEFINER=`root`@`localhost` PROCEDURE `PA_Arribos`(xop int, xidEmpTransport int, xDireccion varchar(150), xnumVuelo int,

                                       xfechaLlegada date, xHoraLlegada time , xnumPersonas int, out xidArribo int)
BEGIN


declare xidArribo int; 

set xidArribo = (select max(idArribos)+1 from arribos);

 
 case xop



     when 1 then

          insert into arribos(idArribos, idEmpTransporte,Direccion,NumVuelo, FechaLlegada, HoraLlegada, NumPersonas)

          values(xidArribo, xidEmpTransport,xDireccion,xnumVuelo,xfechaLlegada, xHoraLlegada, xnumPersonas);
          
          return (select xidArribo);
          
    when 2 then
          select idEmpleado from cliente where idEmpleado = 1;
    
    else
          select 'Operacion no Contemplada';

  end case;

                  

END
Entonces si yo no puedo retornar los valores que quiero desde el when como hago para devolver xidArribo, ya que en otras operaciones suponen otro tipo de devoluciones... creo que me lie :S
  #6 (permalink)  
Antiguo 25/11/2010, 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: retornar un valor desde un procedure

Vamos por partes:
- RETURN pertenece a un STORED FUNCION, no a un STORED PROCEDURE. Tienen una sintaxis similar, pero grandes diferencias: Una función almacenada sólo puede devolver un único dato y de un sólo tipo, el cual se debe declarar en el prototipo. Además todos los parámetros de una SF son IN.

- Si vas a devolver más de un tipo de datos, sólo puedes usar SP, pero con PHP solamente puedes leer el result de la ejecución, por lo que deberás estructurar las respuestas posibles y resolverlo en el código del script. Mi sugerencia es que uses valores numéricos para obtener las respuestas y la resolución de los mensajes la hagas en el PHP.

Algo así:
Código MySQL:
Ver original
  1. -- --------------------------------------------------------------------------------
  2. -- Routine DDL
  3. -- --------------------------------------------------------------------------------
  4. DELIMITER $$
  5.  
  6. CREATE PROCEDURE `PA_Arribos`(
  7.     xop int, xidEmpTransport int,
  8.     xDireccion varchar(150),
  9.     xnumVuelo int,
  10.     xfechaLlegada date,
  11.     xHoraLlegada time ,
  12.     xnumPersonas int,
  13.     OUT xidArribo int)
  14.     CASE xop
  15.         WHEN 1 THEN
  16.             INSERT INTO arribos(idArribos, idEmpTransporte,Direccion,NumVuelo, FechaLlegada, HoraLlegada, NumPersonas)
  17.             VALUES(xidArribo, xidEmpTransport,xDireccion,xnumVuelo,xfechaLlegada, xHoraLlegada, xnumPersonas);
  18.             SET xidArribo  = LAST_INSERT_ID();
  19.             SELECT xidArribo;
  20.         WHEN 2 THEN
  21.              SELECT idEmpleado from cliente where idEmpleado = 1;
  22.         ELSE
  23.              SELECT 'Operacion no Contemplada' Mensaje;
  24.     END CASE;

Prestale atención a un par de cosas:
1) No debes usar DECLARE para declarar variables que tengan el mismo nombre que las que ya vienen en el prototipo. Es un error. Las variables del prototipo ya existen y pueden ser usadas en cualquier parte del codigo del SP.

2) Si el numero de registro es autogenerado, no tiene ninguna utilidad, y puede ser impreciso, usar MAX(x)+1 para obtener el siguiente, porque el siguiente puede no ser ese. El auto_increment se controla de otra forma y el próximo ID autogenerado mysql lo obtiene sobre la base de otra metodología. Por eso precisamente existe la función LAST_INSERT_ID(). Si esta devuelve cero, es que no se insertó nada, caso contrario devuelve el valor real del ID generado.
__________________
¿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 25/11/2010, 10:47
Avatar de Copia  
Fecha de Ingreso: noviembre-2009
Mensajes: 309
Antigüedad: 14 años, 4 meses
Puntos: 4
Respuesta: retornar un valor desde un procedure

hola, gracias por responsder, uso max(idArribos) por que no es autogenerado.
Ahora, bien ahi tengo otra preguna, por ejemple xidArribos esta como OUT, entonces ese valor creo yo que no tengo que pasarlo cuando llamo a este procedimiento pero me da un error.
Si lo paso entonces creo que lo podria modificar con el set xidArribo
  #8 (permalink)  
Antiguo 25/11/2010, 10:56
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: retornar un valor desde un procedure

MySQL no admite recibir menos parámetros de los que el prototipo tiene. Eso significa que no existen en MySQL los parámetros opcionales. Si le pones siete, le tienes que mandar siete.

En el caso que te ocupa, entonces, la idea sería:

Código MySQL:
Ver original
  1. -- --------------------------------------------------------------------------------
  2. -- Routine DDL
  3. -- --------------------------------------------------------------------------------
  4. DELIMITER $$
  5.  
  6. CREATE PROCEDURE `PA_Arribos`(
  7.     xop INT, xidEmpTransport INT,
  8.     xDireccion VARCHAR(150),
  9.     xnumVuelo INT,
  10.     xfechaLlegada DATE,
  11.     xHoraLlegada TIME ,
  12.     xnumPersonas INT,
  13.     OUT xidArribo INT)
  14.     CASE xop
  15.         WHEN 1 THEN
  16.             SELECT MAX(idArribos)+1 FROM arribos INTO xidArribo;
  17.             INSERT INTO arribos(idArribos, idEmpTransporte,Direccion,NumVuelo, FechaLlegada, HoraLlegada, NumPersonas)
  18.             VALUES(xidArribo, xidEmpTransport,xDireccion,xnumVuelo,xfechaLlegada, xHoraLlegada, xnumPersonas);
  19.             SELECT xidArribo;
  20.         WHEN 2 THEN
  21.              SELECT idEmpleado FROM cliente WHERE idEmpleado = 1;
  22.         ELSE
  23.              SELECT 'Operacion no Contemplada' Mensaje;
  24.     END CASE;
__________________
¿A quién le enseñan sus aciertos?, si yo aprendo de mis errores constantemente...
"El problema es la interfase silla-teclado." (Gillermo Luque)
  #9 (permalink)  
Antiguo 25/11/2010, 15:00
Avatar de Copia  
Fecha de Ingreso: noviembre-2009
Mensajes: 309
Antigüedad: 14 años, 4 meses
Puntos: 4
Respuesta: retornar un valor desde un procedure

muchas gracias gonzalo, se que no eres soporte tecnico pero sin abusar de tu generosidad, ni de nadie de este foro, pero tengo un error al ejecutar este procedure.

Error: 1414 SQLSTATE: 42000 (ER_SP_NOT_VAR_ARG)

Mensaje: OUT or INOUT argument %d for routine %s is not a variable or NEW pseudo-variable in BEFORE trigger

Ahora, estube buscando la solucion por internet con translate google, pero encontre alguna solucion que entendiera. Aunque hablaban de sentencias preparadas.
  #10 (permalink)  
Antiguo 25/11/2010, 16:03
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: retornar un valor desde un procedure

El código en si no tiene ningún error sintáctico, al menos para cargarlo con el MySQL Workbench (ya lo probé):

Código MySQL:
Ver original
  1. -- --------------------------------------------------------------------------------
  2. -- Routine DDL
  3. -- --------------------------------------------------------------------------------
  4. DELIMITER $$
  5.  
  6. CREATE DEFINER=`root`@`localhost` PROCEDURE `PA_Arribos`(
  7.     xop INT, xidEmpTransport INT,
  8.     xDireccion VARCHAR(150),
  9.     xnumVuelo INT,
  10.     xfechaLlegada DATE,
  11.     xHoraLlegada TIME ,
  12.     xnumPersonas INT,
  13.     OUT xidArribo INT)
  14.     CASE xop
  15.         WHEN 1 THEN
  16.             SET xidArribo = (SELECT (MAX(idArribos)+1) FROM arribos);
  17.             INSERT INTO arribos(idArribos, idEmpTransporte,Direccion,NumVuelo, FechaLlegada, HoraLlegada, NumPersonas)
  18.             VALUES(xidArribo, xidEmpTransport,xDireccion,xnumVuelo,xfechaLlegada, xHoraLlegada, xnumPersonas);
  19.             SELECT xidArribo;
  20.         WHEN 2 THEN
  21.              SELECT idEmpleado FROM cliente WHERE idEmpleado = 1;
  22.         ELSE
  23.              SELECT 'Operacion no Contemplada' Mensaje;
  24.     END CASE;
  25. END$$

Lo único que se me ocurre es que haya algo en la forma de ejecutarlo donde haya problemas.
¿Exactamente cómo es que estás ejecutando esto? Con qué parámetros y cómo los ingresas?
__________________
¿A quién le enseñan sus aciertos?, si yo aprendo de mis errores constantemente...
"El problema es la interfase silla-teclado." (Gillermo Luque)

Etiquetas: procedure
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 10:28.