Constraint or trigger greater than 18 SQL

0

I need to check when adding a "voter" in the database if it is over 18 years old, I have tried it with a constraint and a check, but it does not support functions for the current date. What other options are there?

ALTER TABLE votantes
ADD CONSTRAINT cns_mayor18 CHECK (YEAR(now()) - YEAR(fechanac) >= 18);
    
asked by Dalfageme 30.01.2017 в 11:04
source

2 answers

2

There are at least 3 problems with your current solution:

1. CHECK constraint does not do anything in most current versions

In all versions of MySQL, as well as all versions of MariaDB prior to 10.2.1, the CHECK constraints do nothing. The syntax exists, but, literally, it does not do anything.

Reference :

  

The CHECK clause is parsed but ignored by all storage engines.

translated (more or less):

  

The clause CHECK is analyzed, but ignored by all storage engines.

2. CHECK constraint only accepts deterministic functions

Starting with MariaDB 10.2.1, you can finally use the CHECK constraints like the other databases But still, there are 2 problems:

  • MariaDB 10.2 is still on BETA.
  • CHECK constraints only accept deterministic functions, so you can not use functions like NOW() , nor CURDATE() .
  • 3. The logic is not correct

    As Pablo Claus commented, even if the CHECK constraint accepts and uses your expression correctly, the logic you have is not correct, because it does not take into account the month and the day, but only the year.

    To obtain the age of a person from a date of birth, the correct way to do it is this way:

    timestampdiff(year, fechanac, now())
    

    Solution

    For the reasons mentioned above, in your case, it seems to me that the only correct solution is to use triggers to carry out the validation. Here is a model of how to do it:

    delimiter $$
    create procedure sp_check_cns_mayor18(in fechanac date)
    begin
      if timestampdiff(year, fechanac, now()) < 18 then
        signal sqlstate '45000' set message_text = 'Votante debe tener 18 años o más.';
      end if;
    end
    $$
    
    create trigger instrg_check_cns_mayor18
    before insert on votantes
    for each row
    begin
      call sp_check_cns_mayor18(new.fechanac);
    end
    $$
    
    create trigger updtrg_check_cns_mayor18
    before update on votantes
    for each row
    begin
      call sp_check_cns_mayor18(new.fechanac);
    end
    $$
    delimiter ;
    
        
    answered by 30.01.2017 / 18:46
    source
    0

    Test with CURDATE() instead of NOW() :

    ALTER TABLE votantes
    ADD CONSTRAINT cns_mayor18 CHECK ((YEAR(CURDATE()) - YEAR(fechanac)) >= 18);
    
        
    answered by 30.01.2017 в 11:43