Calculate difference between dates and change status

Asked

Viewed 906 times

0

I need to create some routine to calculate the difference between two dates directly in the Mysql database and change the status of another field according to this difference. The database fields are :

  1. Date Calibration,
  2. Calibration Expiration,
  3. Calibration status : Up to date, Calibrate, Unsuccessful.

How do I create the routine that takes the two dates make the difference calculation and when the date is more than 30 days the status is "on time", when it is less than 30 days the status is "Calibrate" and when the date is greater than the field "calibration maturity" the status is "Expired" ?

2 answers

3


I will not answer you how to do this in the database, I will propose you a way that (in my opinion) is more suitable for calculated values. Where these calculated fields would not be fields saved in the database but rather calculated based on their indicators.

Upside:

  • The field will be recalculated for each new request, based on the current state of the object;
  • You do not need Procedures, Functions, or Triggers for this task linked to databases;
  • You do not run the risk of the calculated field becoming outdated based on your indicators;
  • Among other numerous minor advantages it is possible to point out easily;

Disadvantages:

  • If the bank is used by more than one system, all those involved must incorporate the rule to calculate the calculated fields;
  • If you do not use Classes template (Assigns the query cursor directly to Datasource (particularly not recommend));

Implementation

It would be something similar to this in C# (which seems to be the language you are using):

public class Calibragem{
    public long Id { get; set; }
    public DateTime Data { get; set; }
    public DateTime Vencimento { get; set; }
    public StatusCalibragem Status { 
        get{
            // aqui você faz a conta da diferença em mémoria
            /** 
             * DUVIDA: aqui você não deveria calcula a Data da ultima calibragem com a 
             * data atual(DateTime.Now) ou o Vencimento com a data atual(DateTime.Now),
             * ao invés de fazer o calculo entre as duas Datas?
            **/    
            TimeSpan diff = Data - Vencimento;

            // verifica a diferença em dias para ver qual o status atual
            if(diff.Days > 30){
                return StatusCalibragem.EmDia;
            }
            if(diff.Days < 30){
                return StatusCalibragem.Calibrar;
            }
            // não entendi quando será Vencida, com sua explicação
        } 
        private set; 
    }
}

public enum StatusCalibragem
{
    EmDia,
    Calibrar,
    Vencida
}

In the database your table would only have columns:

ID | DATA_CALIBRAGEM | VENCIMENTO_CALIBRAGEM
  • I understand Fernando. I will try to apply your example in the system. This way I think I can display these status in my listview. Because besides updating this status I need to display. I have never used classes, but I will try to apply in the code I already have.

  • @Philipesaid, I think it will suit your scenario. And I recommend layering your system and model classes, because using Query Cursor directly in the View may seem practical at first, but as the application grows and maintenance consequently grows as well, Not having layers and classes makes things much more difficult to control. But that’s more of a matter of opinion!

1

To update the column according to the date conditions you can use something like this:

UPDATE suatabela
   SET status = CASE WHEN CURDATE > data_vencimento THEN
                   status1
                ELSE
                   CASE WHEN DATEDIFF(CURDATE(), data_calibragem) > 30 THEN
                      status2
                   ELSE
                      status3
                   END   
                END;

Remember that with this instruction all records in the table will be affected. For at some point, each one will be in one of the 3 situations cited by you.

Remarks:

In order for this instruction to be executed daily you must create a Event in the database (http://dev.mysql.com/doc/refman/5.7/en/events-overview.html).

An example:

delimiter |

CREATE EVENT e_upd_calibragem
    ON SCHEDULE
      EVERY 1 DAY
    COMMENT 'Atualiza status de calibragem'
    DO
      BEGIN

        UPDATE suatabela
           SET status = CASE WHEN CURDATE > data_vencimento THEN
                           status1
                        ELSE
                           CASE WHEN DATEDIFF(CURDATE(), data_calibragem) > 30 THEN
                              status2
                           ELSE
                              status3
                           END   
                        END;

      END |

delimiter ;
  • That code you sent would be a correct Rigger ? Since each bank row has a specific date, this routine would be executed by always calculating all the right lines according to the execution of this event. Trigger would be more suitable than using direct code in the application to make this calculation ?

  • No, this is not a TRIGGER, it is a JOB or in the case of Mysql, an EVENT. This code is scheduled for execution according to the desired period. In the example it would run once a day: ON SCHEDULE EVERY 1 DAY. Thus, each day the table would have all its status updated, since the variation in the status value depends on the date. The advantage of this approach is that execution is scheduled, does not require user intervention, and is independent of application. I can make a web, mobile or desktop app just by consulting the data in the database. Business rules are in the database.

  • I tried to apply your code here but gave error in END CASE.

  • I’m sorry, my mistake. Ends only in END, not END CASE. I fixed the example. In addition there is an UPDATE code working here for you see http://sqlfiddle.com/#! 9/3d1c13 . Access and make a SELECT to test.

  • I tried to run the script you sent but I couldn’t. I’m on to something. The script you posted earlier I already loaded it in mysql, but when I execute I will be signaling error on this line ( UPDATE tb_instrument SET Status = CASE WHEN KURDATE > Data_calibration ). You already loaded the event in the database but did not execute.

  • I managed to execute, but I will have to modify my system, I have a Datetimepicker and a textbox, which are the ones that record the dates. The value of the date I need to use to run the event takes the different date format where the confrontation with the format to be analyzed by the event. But anyway the code you gave me works. I will try to modify this Datetimepicker by a Maskedbox. Thank you very much

  • I’m glad the code came in handy. As for the date format, maybe you can use some function that converts the date to you, either in the application itself or in the database. It is an alternative not to have to change the Datetimepicker.

  • I inserted an event in the database that will do this conversion 'UPDATE tbl_data SET data = DATE_FORMAT(STR_TO_DATE(date, '%d/%m/%Y'), '%Y-%m-%d') WHERE data LIKE '//__' ' . Worked perfectly.

Show 3 more comments

Browser other questions tagged

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