Ver Mensaje Individual
  #1 (permalink)  
Antiguo 18/03/2007, 18:12
digdig
 
Fecha de Ingreso: marzo-2007
Mensajes: 26
Antigüedad: 17 años, 1 mes
Puntos: 0
Generar Localizador Reserva aleatorio con PROCEDURE Y TRIGGER

Hola, después de investigar un poco he descubierto como utilizar PROCEDURE de MySqL para generar un codigo de reserva que tenga 6 caracteres con valores entre A-Z y 0-9 y que tome valores no consecutivos, es decir, aleatorios.
Ejemplos de localizadores de reserva:
R5FCX1
T4WDPD
PNTZ4Z


En primer lugar me creo una tabla con dos columnas (posicion, caracter). Tenemos tantos registros como caracteres A-Z y 0-9, vamos 36 caracteres.
+----------+----------+
| caracter | posicion |
+----------+----------+
| 0 | 0 |
| 1 | 1 |
| 2 | 2 |
| 3 | 3 |
| 4 | 4 |
| 5 | 5 |
| 6 | 6 |
| 7 | 7 |
| 8 | 8 |
| 9 | 9 |
| A | 10 |
| B | 11 |
| C | 12 |
| D | 13 |
| E | 14 |
| F | 15 |
| G | 16 |
| H | 17 |
| I | 18 |
| J | 19 |
| K | 20 |
| L | 21 |
| M | 22 |
| N | 23 |
| O | 24 |
| P | 25 |
| Q | 26 |
| R | 27 |
| S | 28 |
| T | 29 |
| U | 30 |
| V | 31 |
| W | 32 |
| X | 33 |
| Y | 34 |
| Z | 35 |
+----------+----------+
36 rows in set (0.00 sec)



El código para generar el procedimiento es el siguiente:

Código PHP:
DELIMITER $$

DROP PROCEDURE IF EXISTS `test`.`generaLocalizador`$$
CREATE PROCEDURE `test`.`generaLocalizador` (
OUT localizador VARCHAR(6)
)
BEGIN

DECLARE  A1 VARCHAR(1);
DECLARE  
A2 VARCHAR(1);
DECLARE  
A3 VARCHAR(1);
DECLARE  
A4 VARCHAR(1);
DECLARE  
A5 VARCHAR(1);
DECLARE  
A6 VARCHAR(1);

DECLARE  
C1 VARCHAR(1);
DECLARE  
C2 VARCHAR(1);
DECLARE  
C3 VARCHAR(1);
DECLARE  
C4 VARCHAR(1);
DECLARE  
C5 VARCHAR(1);
DECLARE  
C6 VARCHAR(1);

SELECT MOD(FLOOR(RAND()*1000), 35)
INTO A1;
SELECT caracter  as CaracterAleatorio
FROM caracteres
WHERE posicion
A1
INTO C1
;

SELECT MOD(FLOOR(RAND()*1000), 35)
INTO A2;
SELECT caracter  as CaracterAleatorio
FROM caracteres
WHERE posicion
A2
INTO C2
;

SELECT MOD(FLOOR(RAND()*1000), 35)
INTO A3;
SELECT caracter  as CaracterAleatorio
FROM caracteres
WHERE posicion
A3
INTO C3
;

SELECT MOD(FLOOR(RAND()*1000), 35)
INTO A4;
SELECT caracter  as CaracterAleatorio
FROM caracteres
WHERE posicion
A4
INTO C4
;

SELECT MOD(FLOOR(RAND()*1000), 35)
INTO A5;
SELECT caracter  as CaracterAleatorio
FROM caracteres
WHERE posicion
A5
INTO C5
;

SELECT MOD(FLOOR(RAND()*1000), 35)
INTO A6;
SELECT caracter  as CaracterAleatorio
FROM caracteres
WHERE posicion
A6
INTO C6
;

SELECT CONCAT(C1C2C3C4C5C6
INTO localizador;

END$$

DELIMITER 
ANALISIS
MOD(FLOOR(RAND()*1000), 35)
Genera valor aleatorio, multiplica por 1000 y saca el módulo 35. El modulo 35 da valores entre 0 y 35 (Es el resto de dividir un numero entre 35).
Ese valor lo usamos para acceder a la fila de la tabla caracteres y recuperar el valor.

Para ejecutar el procedimiento usamos estas sentencias:

Código PHP:
CALL generaLocalizador(@localizador);

select @localizador
Y nos mostraría la siguiente salida:

+----------------+
| @localizador |
+----------------+
| Q3706Q |
+----------------+


ó

+----------------+
| @localizador |
+----------------+
| ZR2ADS |
+----------------+


etc


Me falta crear el DISPARADOR que llame a mi procedimiento despues de insetar un nuevo registro en la tabla 'reserva' y meta el localizador devuelto por el procedimiento en la clave principal del nuevo registro.
Además tengo que ver como evito que se intente dar un valor de localizador ya existente o como lo detecto para probar con otro valor.

Es la primera vez que trabajo con procedimientos asi que las sugerencias para mejorar mi código o como codificar el TRIGGER son bienvenidas.


Jorge F.M.

Última edición por digdig; 18/03/2007 a las 21:35 Razón: camibo de titulo, Procedure y Trigger