Frage

I have a trigger and stored procedure. In the stored procedure I validate an IPv4 address. If the address is valid it is saved to DB. If not my program saves empty record in the DB. I want to make it so whenever the IP is not valid - nothing to be saved. I don't know how to stop the process when ip is not valid. I know that validation should not be provided at DB level but this is the requirement. Could you help me fixing my code... ? Thanks :)

 DELIMITER $$
CREATE TRIGGER `validation_test_trigger` BEFORE INSERT ON setting_parameters
FOR EACH ROW 
BEGIN 
IF(NEW.parameter_name LIKE 'proxy_test') = true THEN
CALL validate_ip(NEW.parameter_value);
end IF;
END$$
DELIMITER ;
DROP PROCEDURE IF EXISTS validate_ip;
DELIMITER // 
CREATE PROCEDURE validate_ip(INOUT ip VARCHAR(45)) 
BEGIN 
select INET_NTOA(INET_ATON(ip)) into ip;
IF(ip REGEXP '^([1-9]|[1-9][0-9]|1[013-9][0-9]|12[0-689]|2[0-4][1-9]|25[0-4])\.(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){2}([1-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][1-9]|25[0-4])$')=0
THEN
  SIGNAL SQLSTATE '12345'
   SET MESSAGE_TEXT = 'Invalid IP!';
     END IF;
END // 
DELIMITER ; 
War es hilfreich?

Lösung

  1. instead of a procedure, create a function that returns 0 if the IP is correct or 1 of not.
  2. create a table b_setting_parameters like setting_parameters but with ENGINE=BLACKHOLE. That will create a table which discards everything that is inserted into it (like /dev/null)
  3. create the insert trigger on that blackhole table:

    CREATE TRIGGER validation_test_trigger BEFORE INSERT ON b_setting_parameters
    FOR EACH ROW
    BEGIN
      IF validate_ip(NEW.parameter_value) = 0 THEN
        INSERT INTO setting_parameters(col1, col2,...)
        VALUES (NEW.col1, NEW.col2,...)
      END IF;
    END$$
    
  4. now you have to insert into the table b_setting_parameters instead of setting_parameters and it will do the trick.

Andere Tipps

As you have stated, this should not be done at the DB level - I don't believe that MySQL Triggers allow the prevention of an INSERT or UPDATE.

The only way I could see this succeeding is for your Trigger to alter the data so that MySQL cannot insert it... but given that MySQL often manipulates data to fit the table defintion, I'm not sure that will work.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top