Numeración correlativa

126 views
Skip to first unread message

Daniel Fernández, Visualcode.es

unread,
Oct 22, 2015, 5:11:43 AM10/22/15
to CodeIgniter-spanish
Hola Comunidad.

Estoy realizando una aplicación y necesito crear correctamente unas serie números. Lo que necesito es que al guardar un dato por primera vez cree un numero correlativo, que no se repita en la base de datos, del tipo P20151, P20152, P20153, etc..., eso es fácil y se como hacerlo. La pregunta es si conocéis el mejor moda para que si dos o mas usuarios a la vez crean una entrada de este tipo no se suplanten los códigos y pueda fallar.

Tengo una tabla en la base de datos con el último contador guardado, debo recuperarlo sumar 1, guardar el numero contador y guardar el registro, pero sin que otro usuario pueda hacerlo lo mismo que yo y coger ese mismo contador.

Como digo este sistema lo tengo implementado y utilizo $this->db->trans_begin(), de este modo si falla no guarda los cambios.

Lo veis correcto el planteamientos? o me recomendáis algo diferente? Muchas gracias.

edwin_aguiar

unread,
Oct 22, 2015, 5:58:10 AM10/22/15
to CodeIgniter-spanish
Estimado Daniel:
podrias utilizar una funcion que genere tres letras aleatorias mas el timestamp, con eso seguro que jamas vas a repetir nada, ni aun si entran dos peticiones al mismo tiempo ya que al procesar cada operacion se genera una diferencia de tiempo que avanza el incremento.
Cordiales saludos!

Daniel Fernández, Visualcode.es

unread,
Oct 22, 2015, 6:16:41 AM10/22/15
to CodeIgniter-spanish
Hola edwin.

La numeración es para realizar facturas, presupuestos y pedidos, no se si tu opción es la mejor idea, la verdad que no la entendí muy bien. Ahora mismo lo que tengo realizado es un while donde creo un numero y pregunta si existe, hasta que no lo encuentre y entonces lo guardo.

edwin_aguiar

unread,
Oct 22, 2015, 6:24:20 AM10/22/15
to CodeIgniter-spanish
Hola Daniel:
la verdad no, pense que eran id de usuarios. Si lo que buscas es numerar facturas podrias crear un indice que parta de un numero de 6 cifras e incremente, con un campo de comprobacion basado en el timestamp; asi nunca repetiria el id ni tampoco entrarian dos pedidos juntos. Es una idea...
Cuando invocas la funcion de id (numero de presupuesto, pedido o factura -tercer capo podria ser el tipo de operacion) comprueba si el timestamp esta repetido, lo que nunca deberia ocurrir ya que posee exactitud de milesimas de segundo y el mismo sistema te demora lo suficiente al procesar como para que no entren dos iguales; tras comprobar que no existe, te lo guardaria mediante transaccion o directamente en donde lo necesites (la misma tabla) y listo.

Es una idea, disculpame si no soy muy preciso, pero a esta hora de la mañana estoy medio complicado con MongoDB y Codeigniter :D
Un cordial saludo desde Corrientes /Argentina
Edwin

Daniel Fernández, Visualcode.es

unread,
Oct 22, 2015, 6:37:58 AM10/22/15
to CodeIgniter-spanish
Esto es lo que tengo actualmente y funciona, la única duda es si es la mejor opción frente a que otro usuario puede realizar la acción a la misma vez:

$libre = true;
while ($libre) {
//RECUPERAMOS EL CONTADOR SEGUN EL TIPO
$contador = $this->get_contador('0');
//CREAMOS EL NUEVO NUMERO
$num = (int)$contador->co_contador + 1;
$numero = 'PR'.$anio.$num;
//BUSCAMOS UN PRESUPUESTO CON ESTE NUMERO
$aux = $this->get_presupuesto($numero);
//PREGUNTAMOS SI ENCOTRO REGISTROS
if ($aux == null) {
$libre = false;
}
}
$presupuesto['pre_numero'] = $numero;
$this->db->insert('presupuestos',$presupuesto);
//GUARDAMOS EL CONTADOR NUEVO
if ($this->db->trans_status() === TRUE) {
$this->set_contador('0',$num);
}

El jueves, 22 de octubre de 2015, 11:11:43 (UTC+2), Daniel Fernández, Visualcode.es escribió:

edwin_aguiar

unread,
Oct 22, 2015, 7:26:08 AM10/22/15
to CodeIgniter-spanish
Estimado Daniel:
Si funciona no hay necesidad de reinventar la rueda; por mi parte siempre prefiero codigo mas simple (cuando mas lo es mas facil es mantenerlo despues de media hora de haberlo escrito :D ) Mirando tu codigo lo unico que te podria decir es que veo dificil el caso que decis de dos operaciones simultaneas, pero si buscas mas seguridad ademas de comparar $numero podrias comparar si existe el dichoso timestamp en un campo adicional $marca. 
Las dos comparaciones AND en un query incrementan las probabilidades de inexistencia de dicho campo; una vez que comprobas, grabas ambas.
En rojo las ideas; espero que te sean utiles aunque creo que tal como esta ahora tu codigo deberia funcionar sin duplicaciones. 
Disculpa la desprolijidad de la contestacion, justo estamos navegando un embrollo; cordiales saludos

Edwin 

$libre = true;
while ($libre) {
//RECUPERAMOS EL CONTADOR SEGUN EL TIPO
$contador = $this->get_contador('0');
//CREAMOS EL NUEVO NUMERO
$num = (int)$contador->co_contador + 1;                                             // yo hubiera echo $num++
//genero timestamp
$fecha date_create(); $marcadate_timestamp_get($fecha);  //ver manual de php
                                                                               // da salida algo como 1272509157
                                $numero = 'PR'.$anio.$num;
//BUSCAMOS UN PRESUPUESTO CON ESTE NUMERO
$aux = $this->get_presupuesto($numero);

                               //aqui incluir una condicion AND para comparar tambien $marca
                               // cambiando la funcion active record de arriba por otra que admita 
                   //los dos where                              

                                $this->db->select("tu query con los dos campos");                                //manual de CI

 
//PREGUNTAMOS SI ENCOTRO REGISTROS
if ($aux == null) {
$libre = false;
}
}
$presupuesto['pre_numero'] = $numero;
$this->db->insert('presupuestos',$presupuesto);
//GUARDAMOS EL CONTADOR NUEVO
                        y $marca
if ($this->db->trans_status() === TRUE) {
$this->set_contador('0',$num, $marca);
}

Daniel Fernández, Visualcode.es

unread,
Oct 22, 2015, 7:38:35 AM10/22/15
to CodeIgniter-spanish
Muchisimas gracias edwin, es una forma que ni me habia planteado. Gracias desde Cartagena/España. Un saludo.


El jueves, 22 de octubre de 2015, 11:11:43 (UTC+2), Daniel Fernández, Visualcode.es escribió:

edwin_aguiar

unread,
Oct 22, 2015, 8:06:02 AM10/22/15
to CodeIgniter-spanish
Por nada Daniel, un placer ser util a un colega.
Saludos
Edwin
Reply all
Reply to author
Forward
0 new messages