Usamos cookies para medir audiência e melhorar sua experiência. Você pode aceitar ou recusar a qualquer momento. Veja sobre o iMasters.
Olá Amigos
tenho um sistema, e nele ao fazer o cadastro de cobranças, ele gera um código através de uma função, de depois grava no banco.
só que, as vezes são geradas muitas cobranças ao mesmo tempo, tipo 40 a 50 por requisição, um laço cria todas e cada uma tem seu código especifico.
mas, como ja existe muitas e no banco o campo é marcado como único, as vezes aparecem erros, pois acontece de gerar um combinação que ja existe.
no momento, estou usando uma analise simples, gero o código, vejo se já existe, se existir e gera outro e grava, se não grava o que ja estava.
mas essa verificação so acontece uma, e se o outro código gerado na condição também já estiver no banco?
gostaria de saber se alguem sabe algum forma de usar um laço, para que se faça a veriricação até que gere um registro que não esteja no banco.
obrigado
Qualquer FOR/WHILE resolve suponho.
for ($codigo_unico = false, $i = 0; !$codigo_unico && $i < 10; $i++) {
$novo_codigo = funcao_criar_novo_codigo();
$codigo_unico = funcao_que_verifica_codigo_unico_retorna_true_or_false($novo_codigo);
}
Geralmento eu evito WHILEs para não ficar em loop eterno por algum acidente (por isso tem limite de 10 no for).
@Guilherme Luiz deu uma sugestão boa e criar códigos a partir da data, geralmente você consegue códigos quase únicos. Eu pessoalmente para criar um código único, faria algo assim:
<?php uniqid("ID da Chave Primária do Banco de Dados", true); ?>
IDs de chave primárias são únicos, e o uniqid é uma função que é um identificador único com a data em milésimos de segundo.Amigos esse código, tem que ser exclusivamente numérico, e um código de barras simples para carnês de pagamento, com 12 dígitos, uso a seguinte função para gerar os codigos:
function gerabarras(){
$novo_valor= "";
$valor = "0123456789";
srand((double)microtime()*1000000);
for ($i=0; $i<12; $i++){
$novo_valor.= $valor[rand()%strlen($valor)];
}
$codbarras = "01".$novo_valor;
return $codbarras;
}
dai quando vai gravar no banco, as vezes acontece de gerar um que ja esta salvo, e causa erro, preciso de um laço que verifique o código de barras, e veja se já existe, se já existe, tenta de novo, ate aparecer uma combinação que seja únicaAcho que você não entendeu meu FOR quando escrevi, então vou tentar novamente.
for ($codigo_unico = false, $i = 0; !$codigo_unico && $i < 10; $i++) {
$novo_codigo = gerabarras();
$codigo_unico = verificar_codigo($novo_codigo);
}
function verificar_codigo($cod) {
// conecta ao banco e procura se existe este código
// ...
if (!$existe_codigo) {
return true;
}
return false;
}>
Em 09/07/2017 at 01:54, Kosonome disse:
Acho que você não entendeu meu FOR quando escrevi, então vou tentar novamente.
for ($codigo_unico = false, $i = 0; !$codigo_unico && $i < 10; $i++) {
$novo_codigo = gerabarras();
$codigo_unico = verificar_codigo($novo_codigo);
}
function verificar_codigo($cod) {
// conecta ao banco e procura se existe este código
// ...
if (!$existe_codigo) {
return true;
}
return false;
}
eu entenid amigo seu for, mas a quantidade de codigos geradas é variavel, nunca e mesma, pode ser 1, 2 ou 40$code = '';
$numeros = str_split('012345678901234567890', 1);
for ($i = 0; $i < 4; ++$i) {
$code .= $numeros[array_rand($numeros)];
}
$resultado = $code . time();
echo $resultado;
Duvido muito que consiga exibir o mesmo código numérico duas ou mais vezes com isso.
Só que o problema é que está tentando *encontrar chifre em cabeça de cavalo*....
Como o Guilherme disse, é mais vantajoso e correto usar, uma chave primária auto-increment e deixar o SQL fazer a gestão dos dados.É simples, você inicia buscando o código no banco, e não fazendo a inserção.
Tipo assim, select cod_barra from tabela where cod_barra = '123456789102'
'
Após sua função que gera o cod_barras automáticamente, selecione no banco de dados algum codigo que foi gerado pela sua funcao, se não encontrar, cadastre, caso contrario chame a função novamente para gerar um novo código.
Não comece inserindo o código de barras gerado e sim consultando se o codigo gerado já existe.
@icarof
Outra coisa, trabalha com classes no PHP e crie uma classe para gerir e representar suas tabelas e consultas a banco de dados.Amigos, não é questão de criar cifre em cabeça de cavalo, entendam que o campo, de código de barras ja é único, assim como a id, não posso deixar que o banco gerencie, pois esse códigos são dinâmicos, esses dígitos, são adicionados a outros identificadores, tipo: cod_instituição + cod_curso + identificador aluno + código da função, e todas essas combinações são dinâmicas.
Josimar, creio que sua ideia parecer ser a mais sensata, vou testar e ver se da certo
Josimar, sua ideia deu certo em partes, pois ainda encontra conflito.
preciso criar um laço que fique gerando e buscando até encontrar um que passe.
to tentando com Do Whille, mas ainda sem sucesso.
alguma ideia?
Usa o WHILE
Galera, resolvi meu problema, usando o Do While, fiz no primeiro laço 2 verificações como josimar sugeriu, caso nas duas ele nao gere um unico, ele repete o laço.
Uma pergunta e consideração:
Se são novos registros e diferentes registros porque está acontecendo conflito de códigos?
Se você tem a necessidade de criar códigos sequenciais, sugiro que você crie uma tabela somente para estes codigos e deixe o ID como autoincrement e assim você evita esse conflito e deixa a engine do SQL preocupar-se em fazer essa verificação, ou seja, para que tentar reinventar a roda se ela já está ali a sua disposição?!
Se não for essa situação, recomendo que você utilize hash do tipo md5 ou sha1 para estes códigos, mas é preciso atentar-se para que o código "hasheado" não tenha a mesma origem porque assim você vai seguir com o problema de conflito. Uma sugestão? No hash inclua a hora, minutos, segundos e milesimos na composição do hash e assim você dificilmente - quase que impossivel - terá conflito de códigos.