MySQL触发器在插入多次之前检查值

时间:2013-10-29 11:45:34

标签: php mysql triggers

我有一张桌子,可存储最低和最高气温,海水温度为“tinyint”和其他参数。由于我希望新输入在空气中介于-50和+50度之间,我在桌面上做了​​一个触发器。但首先我做了这个程序:

    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

1 个答案:

答案 0 :(得分:1)

在这种特殊情况下,作为其他产品的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);