2013-11-14 91 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. 而不是一個過程,創建一個函數,如果IP正確或返回1,返回0。
  2. 創建表b_setting_parameters類似setting_parameters但與ENGINE=BLACKHOLE。這將創造出丟棄插入它(像/ dev/null的)
  3. 上創建黑洞表的INSERT觸發器一切表:

    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的觸發器允許預防INSERT或UPDATE的。

我可以看到這個成功的唯一方法就是讓你的觸發器改變數據,以便MySQL不能插入它......但是鑑於MySQL經常操縱數據以適應表格定義,我不確定這會起作用。

+0

oracle不支持'INSTEAD OF'觸發器可以做到這一點。對於MySQL,你必須用黑洞引擎插件欺騙(請參閱我的答案) –

相關問題