如果触发器中存在条件,如何在MySQL表中插入记录

时间:2016-07-24 06:03:51

标签: mysql sql

BLUF:我想使用before insert触发器来阻止插入无效数据,而是将该数据存储在另一个表中,并显示错误消息以供日后查看。

我有一张桌子,我的Raspberry Pi气象站正在记录天气数据。有时它出于各种原因而出现硬件故障,当发生这种情况时,它会返回-1000该特定数据点。

我尝试编写一个before insert触发器,可以阻止这些记录与其他有效数据一起写入表中。这部分似乎有效。但我还想把这些错误的记录写到另一张表中。在测试时,坏数据会按预期被拒绝,但没有记录写入错误日志表。

这是我写的触发器:

DROP TRIGGER IF EXISTS wx_beforeInsert;

SET @ERROR_MESSAGE = '';

DELIMITER $$
CREATE TRIGGER `wx_beforeInsert` BEFORE INSERT ON WEATHER_MEASUREMENT 
FOR EACH ROW BEGIN
    IF (NEW.AMBIENT_TEMPERATURE = '-1000') THEN
        SET @ERROR_MESSAGE = "Ambient tempurature invalid. Record rejected.";
    ELSEIF (NEW.GROUND_TEMPERATURE = '-1000') THEN
        SET @ERROR_MESSAGE = "Ground tempurature invalid. Record rejected.";
    ELSEIF (NEW.AIR_QUALITY = '-1000') THEN
        SET @ERROR_MESSAGE = "Air quality invalid. Record rejected.";
    ELSEIF (NEW.AIR_PRESSURE = '-1000') THEN
        SET @ERROR_MESSAGE = "Air pressure invalid. Record rejected.";
    ELSEIF (NEW.HUMIDITY = '-1000') THEN
        SET @ERROR_MESSAGE = "Humidity invalid. Record rejected.";
    END IF;

    IF (@ERROR_MESSAGE <> '') THEN
        INSERT INTO `weather`.`WEATHER_MEASUREMENT_ERRORS`
        (`AMBIENT_TEMPERATURE`,
        `GROUND_TEMPERATURE`,
        `AIR_QUALITY`,
        `AIR_PRESSURE`,
        `HUMIDITY`,
        `WIND_DIRECTION`,
        `WIND_SPEED`,
        `WIND_GUST_SPEED`,
        `RAINFALL`,
        `CREATED`,
        `ERROR_MESSAGE`)
        VALUES
        (NEW.AMBIENT_TEMPERATURE,
        NEW.GROUND_TEMPERATURE,
        NEW.AIR_QUALITY,
        NEW.AIR_PRESSURE,
        NEW.HUMIDITY,
        NEW.WIND_DIRECTION,
        NEW.WIND_SPEED,
        NEW.WIND_GUST_SPEED,
        NEW.RAINFALL,
        NEW.CREATED,
        @ERROR_MESSAGE);

        SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = @ERROR_MESSAGE;
    END IF;
END;
$$

以下是为想要尝试提供帮助的人创建支持表所需的脚本:

CREATE DATABASE IF NOT EXISTS `weather` /*!40100 DEFAULT CHARACTER SET latin1 */;
USE `weather`;

-- Create the WEATHER_MEASUREMENT table if it doesn't exist
CREATE TABLE IF NOT EXISTS `WEATHER_MEASUREMENT` (
  `ID` bigint(20) NOT NULL AUTO_INCREMENT,
  `REMOTE_ID` bigint(20) DEFAULT NULL,
  `AMBIENT_TEMPERATURE` decimal(6,2) NOT NULL,
  `GROUND_TEMPERATURE` decimal(6,2) NOT NULL,
  `AIR_QUALITY` decimal(6,2) NOT NULL,
  `AIR_PRESSURE` decimal(6,2) NOT NULL,
  `HUMIDITY` decimal(6,2) NOT NULL,
  `WIND_DIRECTION` decimal(6,2) DEFAULT NULL,
  `WIND_SPEED` decimal(6,2) NOT NULL,
  `WIND_GUST_SPEED` decimal(6,2) NOT NULL,
  `RAINFALL` decimal(6,4) DEFAULT NULL,
  `CREATED` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
  PRIMARY KEY (`ID`)
) ENGINE=InnoDB AUTO_INCREMENT=4126 DEFAULT CHARSET=latin1;

CREATE TABLE IF NOT EXISTS `WEATHER_MEASUREMENT_ERRORS` (
    `ID` bigint(20) NOT NULL AUTO_INCREMENT,
    `REMOTE_ID` bigint(20) DEFAULT NULL,
    `AMBIENT_TEMPERATURE` decimal(6,2) NOT NULL,
    `GROUND_TEMPERATURE` decimal(6,2) NOT NULL,
    `AIR_QUALITY` decimal(6,2) NOT NULL,
    `AIR_PRESSURE` decimal(6,2) NOT NULL,
    `HUMIDITY` decimal(6,2) NOT NULL,
    `WIND_DIRECTION` decimal(6,2) DEFAULT NULL,
    `WIND_SPEED` decimal(6,2) NOT NULL,
    `WIND_GUST_SPEED` decimal(6,2) NOT NULL,
    `RAINFALL` decimal(6,4) DEFAULT NULL,
    `CREATED` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
    `ERROR_MESSAGE` varchar(50) NOT NULL,
    PRIMARY KEY (`ID`)
) ENGINE=InnoDB AUTO_INCREMENT=4126 DEFAULT CHARSET=latin1;

1 个答案:

答案 0 :(得分:1)

我认为您在WEATHER_MEASUREMENT_ERRORS中的插入也会回滚。 尝试使WEATHER_MEASUREMENT_ERRORS非交易(ROLLBACK不适用于非交易表),使其成为MyISAM表。