我有一个表,每隔5分钟由一个脚本调用更新,由http请求触发。该表看起来像这样
MariaDB > select host_id, ping_eu, disk_usage,insert_time from sequencial_host;
+---------+---------+-------------+---------------------+
| host_id | ping | disk_usage | insert_time |
+---------+---------+-------------+---------------------+
| 1 | 35.60 | 10329416704 | 2016-01-20 20:47:51 |
| 2 | 36.57 | 2902848512 | 2016-01-20 20:48:06 |
+---------+---------+-------------+---------------------+
我想通过调用存储过程来防止乱码,以防脚本运行或任何恶意,如果最后一次insert_time至少是4,5分钟前允许插入。 (30秒脚本内置超时,所以更不准确)。 我建立了这个程序:
CREATE PROCEDURE `update_table`(
IN host_id_a int(11),
IN insert_time timestamp,
IN disk_usage bigint(20) ,
IN ping decimal(10,2)
BEGIN
DECLARE count INT;
SELECT count(insert_time) INTO count FROM db.sequencial_host WHERE insert_time > (NOW() - INTERVAL 270 SECOND) AND host_id = host_id_a ORDER BY insert_time DESC LIMIT 1;
IF count < 1 THEN
INSERT INTO db.sequencial_host ( `host_id`,`insert_time`,`disk_usage`,`ping`)
VALUES( host_id_a, CURRENT_TIMESTAMP, disk_usage, ping);
END IF;
END
如果我省略了If子句,那么插入语句通过调用过程来工作,如果在shell中执行,则Select Query也适用于它自己。 我使用的是MariaDB 5.5.46-1ubuntu0.14.04.2。
我几乎尝试了IF count = 0,IF count IS NULL,IF(SELECT ..)IS NULL的任意组合。
有人可以看一下吗? 亲切的问候Joey
修改
MariaDB [tempdb]> SELECT count(*) FROM tempdb.sequencial_host WHERE insert_time > (NOW() - INTERVAL 270 SECOND) AND host_id = 1 ORDER BY insert_time DESC LIMIT 1;
+--------------------+
| count(insert_time) |
+--------------------+
| 0 |
+--------------------+
1 row in set (0.01 sec)
MariaDB [tempdb]> SELECT count(*) FROM tempdb.sequencial_host WHERE insert_time > (NOW() - INTERVAL 2 HOUR) AND host_id = 1 ORDER BY insert_time DESC LIMIT 1;
+--------------------+
| count(insert_time) |
+--------------------+
| 1 |
+--------------------+
编辑2: 包含所有相关数据库信息的Pastebin完整。 pastebin.com/99eEDLy4
编辑3: 如果我将其更改为cnt = 1,我可以垃圾邮件查询并填充所有内容,但前提是表中有数据。对于刚刚截断的一个,我需要将其设置为0以获取值。
答案 0 :(得分:0)
IF count < 0 THEN
永不运作
将其更改为
IF count > 0 THEN
答案 1 :(得分:0)
指望一个或者为null的列,只返回那些非null的值的计数。如果所有列值都为null,则返回null。
在这种情况下,你的where子句确保没有记录返回,因此insert_Time
的所有列值都将为null;因此返回null。但是,如果您有多个没有空insert_time
的记录;那么计数就代表那些没有空insert_time
的记录。
我认为您希望count(*)
代替count(insert_time)
,以确保在找不到记录时返回0。
CREATE PROCEDURE `update_table`(
IN host_id_a int(11),
IN insert_time timestamp,
IN disk_usage bigint(20) ,
IN ping decimal(10,2))
BEGIN
DECLARE count INT;
SELECT count(*) INTO count FROM db.sequencial_host WHERE insert_time > (NOW() - INTERVAL 270 SECOND) AND host_id = host_id_a ORDER BY insert_time DESC LIMIT 1;
IF count < 1 THEN
INSERT INTO db.sequencial_host ( `host_id`,`insert_time`,`disk_usage`,`ping`)
VALUES( host_id_a, CURRENT_TIMESTAMP, disk_usage, ping);
END IF;
END
答案 2 :(得分:0)
这不是一个错误,它是一个功能。
存储过程内部选择Exists在表中有数据时返回1,如果没有则返回null,当查询写成时(没有在where子句中设置特定表) :
SELECT EXISTS (SELECT * INTO count FROM db.sequencial_host WHERE insert_time > (NOW() - INTERVAL 270 SECOND) AND host_id = host_id_a ORDER BY insert_time DESC LIMIT 1)
;
如果将表附加到主机ID,它将按预期工作。偶数也会返回预期值。 SELECT EXISTS (SELECT * INTO count FROM db.sequencial_host WHERE insert_time > (NOW() - INTERVAL 270 SECOND) AND sequencial_host.host_id = host_id_a ORDER BY insert_time DESC LIMIT 1)
;