0

我有一个触发器和存储过程。在存储过程中,我验证了 IPv4 地址。如果地址有效,则将其保存到 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 ; 
4

2 回答 2

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它会做的伎俩。

于 2013-11-14T15:52:21.267 回答
0

正如您所说,这不应该在数据库级别完成 - 我不相信 MySQL 触发器允许防止插入或更新。

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

于 2013-11-14T15:50:38.740 回答