我正在尝试创建mysql触发器,该触发器应从一个表(raw_us)中获取新插入的数字,将其与最后一条记录进行比较(新值是高于上一个记录,还是低于最后一个记录),并按范围将它们编入值中- 10到10,然后放入另一个表(indexed_us)。我的数据库表:
CREATE TABLE raw_us(rdate DATE,pmi DECIMAL(3,2));
CREATE TABLE indexed_us(idate DATE, ipmi DECIMAL (2,2));
INSERT INTO raw_us(rdate,pmi) VALUES(20000101, 50);
INSERT INTO indexed_us(idate,ipmi) VALUES(20000101, 5);
我编写了触发代码来整理新的原始数据(插入到表raw_us列pmi中)-是新的'pmi'值,它大于还是小于上一个,然后检查新的原始数据属于哪个范围,然后根据特定范围将特定编号插入indexed_us表impi列。这是我的触发代码:
DELIMITER //
CREATE TRIGGER ipmiUS BEFORE INSERT ON raw_us
FOR EACH ROW
BEGIN
DECLARE @old_pmi int;
SET @old_pmi = (select pmi from raw_us where rdate = MAX(rdate));
IF (@old_pmi < NEW.pmi) THEN
IF (50 < NEW.pmi) AND (NEW.pmi < 60)
THEN INSERT INTO indexed_us(idate,ipmi) VALUES (new.date,6);
ELSEIF (60 < NEW.pmi) AND (NEW.pmi < 70)
THEN INSERT INTO indexed_us(idate,ipmi) VALUES (new.date,7);
END IF;
ELSEIF (@old_pmi > NEW.pmi) THEN
IF (50 > NEW.pmi) AND (NEW.pmi > 60)
THEN INSERT INTO indexed_us(idate,ipmi) VALUES (new.date,5);
ELSEIF (40 > NEW.pmi) AND (NEW.pmi > 50)
THEN INSERT INTO indexed_us(idate,ipmi) VALUES (new.date,4);
END IF;
END IF;
END; //
DELIMITER ;
问题是,在将触发器更新为“插入前”并在IF语句的范围内固定为“ IF(数字> NEW.pmi)和(NEW.pmi>数字)”之后,我只是报错:
您的SQL语法有误;检查与您的MySQL服务器版本相对应的手册,以在第1行的'DELIMITER // CREATE TRIGGER ipmiUS插入到raw_us FOR EACH ROW上之前使用正确的语法。
最佳答案
您很可能对IF
表达式有疑问。您在编写“范围内” (30 < NEW.pmi < 40)
的方式不会产生预期的结果。
为了清楚起见,请尝试以下操作:
SELECT
30 < 1 < 40 ;
您得到的回应:
| 30 < 1 < 40 | | ----------: | | 1 |
This is because MySQL is actually computing:
SELECT
(30 < 1) < 40 ;
(30 < 1)
的结果为false
,由MySQL表示为0
,然后(0 < 40)
为true
,并表示为1
。您需要像这样重写条件:
IF (30 < NEW.pmi) AND (NEW.pmi < 40) THEN
-- whatever
...
另外,还要考虑到一些极端情况没有被考虑在内。例如,当
40 = NEW.pmi
时,您可能希望发生某些事情。检查范围时,最好进行如下比较:`(lower_bound <= value) AND (value < upper_bound)`
(请注意
<=
和<
)。另请注意,您可以编写(注意
(lower_bound <= value) AND (value <= upper_bound)
具有等效形式
value BETWEEN lower_bound AND upper_bound
仅当您处理
INTEGER
或DECIMAL
时,这是一个好习惯,但如果您使用FLOAT
,则不是。请参见dbfiddle here上的整个示例