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

Procedimiento Almacenado Variables

Estas en el tema de Procedimiento Almacenado Variables en el foro de Mysql en Foros del Web. Buenas noches, Soy nuevo en procedimientos almacenados, y pretendia hacer uno para no tener que codificar lo mismo en php. Y que asi sea mas ...
  #1 (permalink)  
Antiguo 11/03/2008, 18:25
 
Fecha de Ingreso: enero-2008
Mensajes: 7
Antigüedad: 16 años, 2 meses
Puntos: 0
Procedimiento Almacenado Variables

Buenas noches,

Soy nuevo en procedimientos almacenados, y pretendia hacer uno para no tener que codificar lo mismo en php. Y que asi sea mas rapido ( aunque no hace casi nada ) es mas por no tener que codificarlo en php.

AL tema, se que fijo que hay formas mejores de hacerlo pero crei que asi funcionaria

Código:
DELIMITER $$

DROP PROCEDURE IF EXISTS `hola`.`vacdestra`$$
CREATE PROCEDURE `hola`.`vacdestra` ()
BEGIN
DECLARE total INT;
DECLARE actual INT;
DECLARE vac INT;
DECLARE tra INT;
DECLARE des INT;
DECLARE dni VARCHAR(9);
DECLARE tabla VARCHAR(6);
SET actual=0;
SET vac=0;
SET tra=0;
SET des=0;

SELECT CONCAT( MONTH(CURRENT_DATE) , YEAR(CURRENT_DATE) ) INTO tabla;

CREATE TABLE tabla (
conductor VARCHAR(9) ,
t TINYINT(2) ,
d TINYINT(2) ,
v TINYINT(2) );

SELECT COUNT(DISTINCT conductor) INTO total FROM vacdestra;

WHILE actual < total DO

  SELECT conductor INTO dni FROM vacdestra LIMIT actual,1;
  SELECT COUNT(*) INTO vac FROM vacdestra WHERE conductor=dni AND actividad="V";
  SELECT COUNT(*) INTO tra FROM vacdestra WHERE conductor=dni AND actividad="T";
  SELECT COUNT(*) INTO des FROM vacdestra WHERE conductor=dni AND actividad="D";

  INSERT INTO tabla VALUES ( tra , des , vac );

  SET actual = actual + 1;
END WHILE;

END$$

DELIMITER ;
Dos problemas, el primero, no me crea el procedimiento por el LIMIT, me da error en actual, si le pongo solo 1 lo crea ( necesito el actual ) y el segundo , crea la tabla con nombre tabla y no lo que deberia valer la variable tabla.

Alguna idea?

Gracias.

Última edición por MinoX; 11/03/2008 a las 18:45 Razón: Faltaban cosas en la explicacion.
  #2 (permalink)  
Antiguo 11/03/2008, 19:15
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
Re: Procedimiento Almacenado Variables

Los nombres de las tablas tienen prioridad sobre los nombres asignados a las variables.
Pudiera decirse:
- Tabla mata a campo.
- Campo mata a variable.
En síntesis: No uses los mismos nombres para diferentes objetos o de lo contrario los resultados serán erráticos.

Además, mira bien el manual de referencia en el tema de procedimientos almacenados. Estás tratando de crear una traza de tabla por registro, cuando ya existen en MySQL sentencias y métodos mucho más eficientes para hacer el trabajo.
Me refiero puntualmente a esto:
Código:
WHILE actual < total DO

  SELECT conductor INTO dni FROM vacdestra LIMIT actual,1;
  SELECT COUNT(*) INTO vac FROM vacdestra WHERE conductor=dni AND actividad="V";
  SELECT COUNT(*) INTO tra FROM vacdestra WHERE conductor=dni AND actividad="T";
  SELECT COUNT(*) INTO des FROM vacdestra WHERE conductor=dni AND actividad="D";

  INSERT INTO tabla VALUES ( tra , des , vac );

  SET actual = actual + 1;
END WHILE;
Esto está mal, se hace de otra forma. Mirá este link: 19.2.11. Cursores

Como consejo, no hagas trazados donde puedas resolver con consultas...
Imaginate algo así:
Código:
INSERT INTO tabla
SELECT 
  conductor,
  SUM(IF(actividad='V',1,0)),
  SUM(IF(actividad='T',1,0)),
  SUM(IF(actividad='D',1,0))
FROM vacdestra
GROUP BY conductor;
Eso debería hacer:
- 1 full scan.
- Agrupar por conductor.
- Sumar 1 por cada coincidencia en cada comparación por cada registro leído.
- Insertar cada registro resultante en la tabla nueva.

Última edición por gnzsoloyo; 11/03/2008 a las 19:25
  #3 (permalink)  
Antiguo 11/03/2008, 19:28
 
Fecha de Ingreso: enero-2008
Mensajes: 7
Antigüedad: 16 años, 2 meses
Puntos: 0
Re: Procedimiento Almacenado Variables

Gracias por tu respuesta, yo lo havia visto en un pdf que hay de cuando sacaban la version 5.0 que explicaban los procedimientos. Pero no lo habia entendido. Y El problema del nombre de la tabla como se puede solucionar, necesito que la tabla se llame como el numero de mes mas el numero de año. Por eso hacia esa concatenacion. Hay alguna otra forma de hacerla, ya que dices que las tablas valen mas que las variables. nno hay forma?.

Gracias.
  #4 (permalink)  
Antiguo 11/03/2008, 19:42
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
Re: Procedimiento Almacenado Variables

Técnicamente no. Pero haz la prueba precediendo el nombre de las variables con "@", como dice el estándar de SQL. Puede que funcione.
La única solución que he encontrado es implementarlo a través de código en las aplciaciones, ya sea VB.Net o C#.Net, desde las que podés secuenciar un conjunto de sentencias de MySQL que se vayan ejecutando, y desde allí construir la sentencia de creación de la tabla con el nombre deseado.
De todos modos, eso elimina la posibilidad de usar procedimientos almacenados, pero no de lograr lo que estás buscando, aunque para eso deberías meditarlo de otra forma.
  #5 (permalink)  
Antiguo 11/03/2008, 19:57
 
Fecha de Ingreso: enero-2008
Mensajes: 7
Antigüedad: 16 años, 2 meses
Puntos: 0
Re: Procedimiento Almacenado Variables

Muchas gracias, con la @ no lo he conseguido. Pues me tendre que crear un fichero php para cada uno de los procedimientos. Esque estaba pensado para que en el index evaluase que dia es y si es comienzo de mes, llamase con un call y la bd hiciera todo el trabajo, pero al final lo tendre que codificar.

Muchas gracias por todo. Me pasare a la filosifia que conozco que es la de mysql con php.

Saludos.
  #6 (permalink)  
Antiguo 12/03/2008, 04:10
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
Re: Procedimiento Almacenado Variables

No necesariamente.
Por lo que entiendo estás intentando diferenciar un conjunto de 3 valores que deben identificarse para cada conductor en un mes y año determinados. para eso no necesitas una tabla por cada mes, sino una tabla que tenga esos dos campos y una clave de indice compuesta por los tres valores.
Al estilo:
Código:
CREATE TABLE ResumenServicios(
id_servicio INT AUTO_ICREMENT PRIMARY KEY,
nro_mes INT NOT NULL,
nro_annio INT NOT NULL,
conductor VARCHAR(9)  NOT NULL,
t TINYINT(2) ,
d TINYINT(2) ,
v TINYINT(2) , 
);
En este caso, lo único que tienes que hacer es un indice UNIQUE por los 3 campos necesarios. La tabla sería funcional y podrías usarla en un SP. Además, las consultas de todos modos serían mucho más simple.
Si lo que deseas, a partir de ella es tener acceso a los datos parciales de un mismo año, en forma de archivo, lo único que tienes que hacer es un volcado de la misma como tabla a otra tabla, si creada ex-profeso por código. Sino, no tiene utilidad funcional separarlos por año y mes.
  #7 (permalink)  
Antiguo 12/03/2008, 04:16
 
Fecha de Ingreso: enero-2008
Mensajes: 7
Antigüedad: 16 años, 2 meses
Puntos: 0
Re: Procedimiento Almacenado Variables

Al final lo he arreglado con la misma tabla que tenia pensada.
TOTALVACDESTRA(
conductor,
mes,
anyo,
t,
d,
v
)
Y como clave primari las tres primeras, asi nunca se me puede repetir un dato que no se tiene que repetir. Y como cada mes de cada año solo se almacena una fila por cada conductor y no son muchos datos. Asi ya lo hice con un SP. Le digo que inserte el mes y el año en el propio procedimiento, con lo que cumple el que la tarea se automatiza como yo queria.

Muchas gracias por la respuesta, al final lo consegui resolver y utilizando cursor.

Saludos.

PD: Ahora que he vuelto a reeler tu ultima respuesta, es igual a como al final lo saque.xD.

Última edición por MinoX; 12/03/2008 a las 04:17 Razón: Se me olvido escribir.
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:12.