2013-10-29 85 views
2

我有一個表女巫商店的最低和最高氣溫,海水溫度爲「tinyint」和其他參數。由於我預計新輸入的空氣在-50到+50度之間,因此我在桌面上觸發了一個觸發器。但是首先我做了這個過程:MySQL觸發器在插入多次之前檢查值

begin 
    if temp<-50 or temp>50 then 
    set sts = 0; 
    else 
    set sts = 1; 
    end if; 
    END 

觸發:

BEGIN 
    declare err boolean; 
    declare msg varchar(255); 
    call check_temp(NEW.Tmin,err); 
    IF err!=1 THEN 
    set msg = "Error: Tmin out of range."; 
    SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = msg; 
    END IF; 

    call check_temp(NEW.Tmax,err); 
    IF err!=1 THEN 
    set msg = "Error: Tmax out of range."; 
    SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = msg; 
    END IF; 
    END 

正如你所看到的,我叫check_temp兩次的最大值和最小值。 由於我有更多的氣象參數列,我需要將他們的「範圍檢查」添加到上述觸發器。

我的問題是:這是最明智的做法嗎?像這樣使用這個程序兩次(並且一旦我添加海水溫度它們將會是三次),對我來說看起來很愚蠢。並在觸發器中逐個檢查所有8個參數?我每次插入大約50行。觸發器會慢得多嗎?到目前爲止,我使用了PHP端檢查,但決定改用數據庫功能。我可以使用這種觸發器,還是其目的完全不同?任何意見的話題將不勝感激。 MySQL是5.5.27

+0

那麼,爲什麼不在PHP中處理這個問題,並且如果數據不符合您的驗證條件,就完全保存數據庫訪問權限?事實上,使用這個觸發器,您將不得不處理PHP代碼中由觸發器產生的任何錯誤,並將適當的錯誤消息傳遞給用戶。通過分離PHP和MySQL之間的驗證邏輯,你獲得了什麼? –

+0

我曾經這麼做過,但事實證明這很不方便。現在我使用Java腳本進行人機輸入,並使用觸發器進行機器輸入。謝謝。 –

回答

0

作爲其他產品的CHECK Constraints的功能在這種情況下是合適的,但MySQL不支持此功能。通常使用觸發器來實現你所需要的。

在以下示例中,非常基本的所有列都在觸發器上進行了驗證,並且當您嘗試插入50條記錄時,它需要幾毫秒。這只是一個概念驗證,對於您在類似生產環境中執行測試會很方便。

/*Table structure for table `table_variables` */ 

DROP TABLE IF EXISTS `table_variables`; 

CREATE TABLE `table_variables` (
    `id` INT(10) UNSIGNED NOT NULL AUTO_INCREMENT, 
    `variable0` TINYINT(4) DEFAULT NULL, 
    `variable1` TINYINT(4) DEFAULT NULL, 
    `variable2` TINYINT(4) DEFAULT NULL, 
    `variable3` TINYINT(4) DEFAULT NULL, 
    `variable4` TINYINT(4) DEFAULT NULL, 
    `variable5` TINYINT(4) DEFAULT NULL, 
    `variable6` TINYINT(4) DEFAULT NULL, 
    `variable7` TINYINT(4) DEFAULT NULL, 
    PRIMARY KEY (`id`) 
) ENGINE=INNODB; 

/* Trigger structure for table `table_variables` */ 

DELIMITER $$ 

/*!50003 DROP TRIGGER*//*!50032 IF EXISTS */ /*!50003 `trg_check_bi` */$$ 

CREATE TRIGGER `trg_check_bi` BEFORE INSERT ON `table_variables` 
FOR EACH ROW 
BEGIN 
    DECLARE msg VARCHAR(255); 
    DECLARE _min, _max TINYINT DEFAULT -49; 
    SET _max := _max * (-1); 
    SET @max = _max; 
    IF (new.`variable0` NOT BETWEEN _min AND _max) THEN 
     SET msg := 'Error: variable0 out of range.'; 
     SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = msg; 
    END IF; 
    IF (new.`variable1` NOT BETWEEN _min AND _max) THEN 
     SET msg := 'Error: variable1 out of range.'; 
     SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = msg; 
    END IF; 
    IF (new.`variable2` NOT BETWEEN _min AND _max) THEN 
     SET msg := 'Error: variable2 out of range.'; 
     SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = msg; 
    END IF; 
    IF (new.`variable3` NOT BETWEEN _min AND _max) THEN 
     SET msg := 'Error: variable3 out of range.'; 
     SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = msg; 
    END IF; 
    IF (new.`variable4` NOT BETWEEN _min AND _max) THEN 
     SET msg := 'Error: variable4 out of range.'; 
     SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = msg; 
    END IF; 
    IF (new.`variable5` NOT BETWEEN _min AND _max) THEN 
     SET msg := 'Error: variable5 out of range.'; 
     SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = msg; 
    END IF; 
    IF (new.`variable6` NOT BETWEEN _min AND _max) THEN 
     SET msg := 'Error: variable6 out of range.'; 
     SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = msg; 
    END IF; 
    IF (new.`variable7` NOT BETWEEN _min AND _max) THEN 
     SET msg := 'Error: variable7 out of range.'; 
     SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = msg; 
    END IF; 
END $$ 

DELIMITER ; 

INSERT `table_variables` (
    `variable0`, 
    `variable1`, 
    `variable2`, 
    `variable3`, 
    `variable4`, 
    `variable5`, 
    `variable6`, 
    `variable7`) 
VALUES 
    (25, 46, 6, 42, 46, -42, -6, 47), 
    (11, -37, 26, -3, -44, 37, -28, -4), 
    (14, 33, -21, 40, 19, 23, 10, 29), 
    (-32, 1, -47, 10, 42, 36, 5, -34), 
    (-38, -40, -35, -6, 27, 7, 4, -49), 
    (-14, 29, 41, -29, -23, 22, 31, 41), 
    (-34, -49, 5, 27, -27, 30, -14, -11), 
    (36, -30, -14, -27, -44, 10, 33, -12), 
    (-10, 34, -42, 29, 29, 10, 11, -21), 
    (6, 45, -36, 29, 7, -3, 13, 25), 
    (37, -35, -40, -47, 32, -42, 38, -27), 
    (-4, 12, 24, 36, -39, 41, -22, 12), 
    (-19, 14, -18, 16, -15, 27, 31, 28), 
    (-3, -49, 11, -44, -8, 42, -8, -21), 
    (-31, -44, 21, -6, -42, -47, 38, -11), 
    (-21, -23, -1, 17, 36, -16, -40, -3), 
    (-43, 40, -16, 48, 43, 22, 29, 32), 
    (25, -21, -32, -47, 6, 28, -28, 23), 
    (-45, -48, 42, 11, -22, 4, 36, 24), 
    (-39, -21, -34, 39, -47, -10, 46, 16), 
    (-10, -48, 37, -15, -37, 8, 5, -47), 
    (-4, -25, 32, -8, 11, 31, -25, 26), 
    (-40, -30, 20, 44, 12, -22, -1, 16), 
    (32, -33, -14, -22, -19, 20, 13, -43), 
    (-10, 31, 39, -44, 8, 23, 44, 3), 
    (32, 3, -31, -15, -32, 34, 20, 47), 
    (30, -42, 44, 5, 41, 43, 44, 43), 
    (32, -16, -31, 43, -34, 45, -14, 37), 
    (-15, -38, 3, -17, -46, -31, 33, 12), 
    (13, -22, 0, 18, 42, 9, -31, -33), 
    (-23, 32, -16, -27, -38, 38, -40, 30), 
    (26, -9, 23, -4, -38, -31, 9, -11), 
    (-31, 25, -24, 48, -30, 48, -10, -47), 
    (41, 1, 31, 4, -21, 30, -33, -9), 
    (8, 16, 7, 39, 25, -38, -23, -47), 
    (-18, 1, 13, 13, -25, -14, -43, -25), 
    (-47, -11, 38, -23, 15, 0, 3, -31), 
    (-20, 44, 37, 4, -40, 33, 39, 47), 
    (-29, -40, 35, -46, 6, 21, 41, -4), 
    (4, -16, -42, -16, -1, -6, 23, -13), 
    (14, -40, 5, 0, 32, 16, 34, -24), 
    (24, 45, 7, -49, -22, -12, -43, -29), 
    (32, 1, -41, 38, -28, -11, -17, -5), 
    (-21, -39, 13, 37, -1, 32, 17, 40), 
    (-1, 25, -20, -26, -22, 18, 8, 37), 
    (13, 4, 32, 1, -41, 36, -38, 47), 
    (4, 26, -29, 25, -33, 5, -24, 15), 
    (-1, -1, 47, -4, -15, -11, 36, -29), 
    (-9, -7, 42, -14, -48, 47, 39, 3), 
    (-31, -20, 91, 17, -89, 4, -14, 22);