如何防止从触发器或存储过程保存到数据库?

时间:2013-11-14 15:40:25

标签: mysql triggers ipv4

我有一个触发器和存储过程。在存储过程中,我验证IPv4地址。如果地址有效,则将其保存到DB。如果不是我的程序在DB中保存空记录。每当IP无效时我都想这样做 - 没有什么可以保存的。当ip无效时,我不知道如何停止进程。我知道不应该在数据库级别提供验证,但这是要求。你能帮我修一下我的代码......?谢谢:))

 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 ; 

2 个答案:

答案 0 :(得分:1)

  1. 而不是过程,创建一个函数,如果IP正确则返回0,或者返回1。
  2. 创建一个表b_setting_parameters,例如setting_parameters,但ENGINE=BLACKHOLE。这将创建一个表,丢弃插入其中的所有内容(如/ dev / null)
  3. 在该黑洞表上创建插入触发器:

    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. 现在您必须插入表b_setting_parameters而不是setting_parameters,这样才能解决问题。

答案 1 :(得分:0)

正如您所说,这不应该在数据库级别完成 - 我不相信MySQL触发器允许阻止INSERT或UPDATE。

我能看到这个成功的唯一方法是你的触发器改变数据,以便MySQL不能插入它......但鉴于MySQL经常操纵数据以适应表格定义,我不确定它是否会起作用。