我正在尝试创建 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行的"分隔符//在插入每行raw_us之前创建触发器IPMIUS"附近使用的正确语法。
您很可能对IF
表达式有问题。您正在以不产生预期结果的方式编写"范围内"(30 < NEW.pmi < 40)
。
为了清楚起见,请尝试以下操作:
SELECT
30 < 1 < 40 ;
您得到的响应是:
|30 <1 <40 | |----------: | | 1 |
这是因为MySQL实际上是在计算:
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
s 或DECIMAL
s 时是一种很好的做法,但如果您使用FLOAT
s,则不然。
在此处查看 dbfiddle的完整示例