2013-11-14 5 views
0

У меня есть триггер и хранимая процедура. В хранимой процедуре я проверяю адрес IPv4. Если адрес действителен, он сохраняется в БД. Если моя программа не сохраняет пустую запись в БД. Я хочу сделать это так, когда 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 ; 

ответ

1
  1. вместо процедуры создайте функцию, которая возвращает 0, если IP-адрес правильный или 1 нет.
  2. создать стол b_setting_parameters как setting_parameters но с ENGINE=BLACKHOLE. Это создаст таблицу, которая отбрасывает все, что вставляется в него (как/DEV/нуль)
  3. создать триггер вставки на этой BLACKHOLE таблице:

    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, и он будет делать трюк.

0

Как уже говорилось, это не должно быть сделано на уровне БД - Я не верю, что MySQL Триггеры позволяют предотвратить вставки или изменения.

Единственный способ, которым я мог видеть это, - это заставить Trigger изменять данные, чтобы MySQL не мог их вставить ... но учитывая, что MySQL часто манипулирует данными, чтобы они соответствовали определению таблицы, я не уверен, что это сработает ,

+0

Оракул поддерживает триггер 'INSTEAD OF', который может это сделать. Для mysql вам нужно обмануть плагин с двигателем черной дыры (см. Мой ответ) –

Смежные вопросы