C# Generate random and unique number, check the database if any equal number has already been generated and if you have to generate another number again

Asked

Viewed 180 times

-2

I’m developing a system where I need to generate one random number and single and write to the bank, this system will run every day generating new numbers based on business rules.

With the help of colleagues in the comments I modified my code, now putting in the bank the column "coupon" as unique, so when trying to record will never allow if there is already an equal value in the bank.

My problem now is that when it happens that there already exists a number equal to what was generated, my system generates a recording error and I can’t make it generate a new number to try to record again.

I need that when I can not record because the number already exists it enters in "loop", generating a new coupon until it is not in the bank and can continue the execution.

To generate the random number:

 public string CupomCampanha()
        {
              string numeroAleatorio = "";
              var random = new Random();
              var possibilidades = Enumerable.Range(0, 10).ToList();
              var resultado = possibilidades.OrderBy(number => random.Next()).Take(10).ToArray();
              return numeroAleatorio = String.Join("", resultado);
        }

To do the Insert in the bank

public void InserirIndicacaoContas(string cpf)
        {
              if (cpf != "-")
              {
                    var conexao = AbrirConexao();
                    var comando = conexao.CreateCommand();

                    comando.CommandText =
                    $"INSERT INTO campanhaCupons (cpf, cupon, idProduto, dataImportacao) VALUES (@cpf, @cupon, @idProduto, @dataImportacao)";
                    comando.Parameters.AddWithValue("cpf", cpf);
                    comando.Parameters.AddWithValue("cupon", _geraCupon.CupomCampanha());
                    comando.Parameters.AddWithValue("idProduto", "1");
                    comando.Parameters.AddWithValue("dataImportacao", Convert.ToDateTime(DateTime.Now).ToString("yyyy/MM/dd HH:mm:ss"));

                    ExecutaComando(comando);
              }

I hope I can explain better now.

  • 1

    For having extended himself in the comments, the conversation was moved to the chat and can proceed there by the link provided

  • The questions here need to explain objectively and punctually the difficulty found, accompanied by a [mcve] problem and attempt to solve. To better enjoy the site, understand and avoid closures and negativations worth understanding What is the Stack Overflow and read the Stack Overflow Survival Guide (summarized) in Portuguese. Moreover, from the wording of the question, this is probably a XY problem, worth a read on the link.

  • Reversed. Do not change the scope of questions after they have been accepted. If you want to modify first take the acceptance or ask a new question.

1 answer

2


As I said in the comments :

  • The coupon number you will always have to create, randomly as specified, but making the table column have the restriction UNIQUE DB itself prevents you from adding a duplicate coupon number thus saving time to program a search for duplicity in the database.

  • When trying to duplicate a record in a column UNIQUE an exception is made. Use this exception in your favor put the code in a loop within a treatment of exceptions, If you make a mistake repeat the loop and generate another coupon number otherwise it is wrong that the coupon has been saved and leave the loop.

Applied in the example:

while (true){
  var comando = conexao.CreateCommand();      //Cria um novo comando sql.
  comando.CommandText =
  $"INSERT INTO campanhaCupons (cpf, cupon, idProduto, dataImportacao) VALUES (@cpf, @cupon, @idProduto, @dataImportacao)";
  comando.Parameters.AddWithValue("cpf", cpf);
  comando.Parameters.AddWithValue("cupon", _geraCupon.CupomCampanha());
  //Abre um bloco de tratamento de exceções...
  try{
     ExecutaComando(comando);  //Quando não conseguir inserir registro gera uma exceção MySqlException.
  catch {
      continue;                //Se uma exceção foi gerada reitera o loop.    
  }
  break;                       //Caso nenhuma exceção tenha sido gerada abandona o loop
}
  • 1

    Test the code before voting or accepting. There may be errors because I did it in my head, I have no way to test because I don’t have a copy of your DB and I won’t do a db mock in the new year.

  • 1

    Despite answering (in a way) the question, imagine when the number pool is saturated, and you start having successive key violations, until you get lucky to catch a free number. Unfortunately, the author’s request is already part of a conceptual problem.

  • @Augustovasques tested here but he is not falling in the catch when the number already exists in the bank, from Try he already goes to the end of the while and does not repeat the loop. Os 2 erros que recebo no console são: Exception thrown: 'MySql.Data.MySqlClient.MySqlException' in MySql.Data.dll
Erro ao executar query: Duplicate entry '2960473185' for key 'campanhacupons.campanhaCupons_UN' || LINHA: at MySql.Data.MySqlClient.MySqlStream.ReadPacket()

  • 1

    I edited the answer.

  • 1

    It worked out here, thank you so much for all your help, happy new year to you and your whole family!

  • 1

    I would like to make some considerations, suggesting some good practices. First, keep in mind the business rule of what you intend to develop. So yes, you should leave the column that will receive this number as UNIQUE in your table in the database. Would it help in validation? NO! It is for the modeling to be compatible with your business, in bank is NOT used, or should not use, business rule. Second, using "Exception" for business rule is not correct (I see many developers using for such purpose). The name already says that is an exception to the rule. What rule? In this case, business!

  • @Leandroamarilha, thanks for the guidelines.

Show 2 more comments

Browser other questions tagged

You are not signed in. Login or sign up in order to post.