意外的MySQL INT字段处理日期时间输入

时间:2018-04-10 12:03:38

标签: mysql sql mysqli int

我的数据库中有以下表格之一,其中显示了“显示创建表格”的输出。分享:

CREATE TABLE `clues_rma_efficacy_triggers` (
 `id` int(11) NOT NULL AUTO_INCREMENT,
 `data` int(11) NOT NULL DEFAULT '0',
 `data_type` char(1) NOT NULL,
 `parent_key_id` tinyint(3) NOT NULL DEFAULT '0',
 `child_key_id` tinyint(3) NOT NULL DEFAULT '0',
 `parent_flag` tinyint(3) NOT NULL DEFAULT '0',
 `child_flag` tinyint(3) NOT NULL DEFAULT '0',
 `datetime` int(11) NOT NULL,
 PRIMARY KEY (`id`),
 UNIQUE KEY `data_child_key` (`data`,`parent_key_id`,`child_key_id`),
 KEY `idx_pki_cf_cki` (`parent_key_id`,`child_flag`,`child_key_id`),
 KEY `idx_pki_pf` (`parent_key_id`,`parent_flag`),
 KEY `idx_cki_cf` (`child_key_id`,`child_flag`)
) ENGINE=InnoDB AUTO_INCREMENT=32436413 DEFAULT CHARSET=latin1

如您所见,datetime列是int字段,其中我存储unix_time值。但是我为SELECT查询之一获得了意外行为。生产步骤如下:

1个样本插入:

INSERT INTO `clues_rma_efficacy_triggers` (`data`,`data_type`,`parent_key_id`,`datetime`) VALUES (1234568197,'R',89,1522933144);

mysql> select * from clues_rma_efficacy_triggers where data = 1234568197;
+----------+------------+-----------+---------------+--------------+-------------+------------+------------+--------------+
| id       | data       | data_type | parent_key_id | child_key_id | parent_flag | child_flag | datetime   | deleted_flag |
+----------+------------+-----------+---------------+--------------+-------------+------------+------------+--------------+
| 34905336 | 1234568197 | R         |            89 |            0 |           0 |          0 | 1522933144 |            0 |
+----------+------------+-----------+---------------+--------------+-------------+------------+------------+--------------+
1 row in set (0.01 sec)

下面的查询不应该获取结果,但是它正在获取结果(它忽略了完整的datetime子句并且正在处理parent_key_id和parent_flag)

SELECT * , from_unixtime( datetime ) FROM clues_rma_efficacy_triggers WHERE datetime BETWEEN (NOW( ) - ( 86400 *30 )) AND NOW( ) AND parent_key_id =89 AND parent_flag =0 LIMIT 200;

mysql> SELECT * , from_unixtime( datetime ) FROM clues_rma_efficacy_triggers WHERE datetime BETWEEN (NOW( ) - ( 86400 *30 )) AND NOW( ) AND parent_key_id =89 AND parent_flag =0 LIMIT 200 ;
+----------+------------+-----------+---------------+--------------+-------------+------------+------------+--------------+---------------------------+
| id       | data       | data_type | parent_key_id | child_key_id | parent_flag | child_flag | datetime   | deleted_flag | from_unixtime( datetime ) |
+----------+------------+-----------+---------------+--------------+-------------+------------+------------+--------------+---------------------------+
| 34905336 | 1234568197 | R         |            89 |            0 |           0 |          0 | 1522933144 |            0 | 2018-04-05 18:29:04       |
+----------+------------+-----------+---------------+--------------+-------------+------------+------------+--------------+---------------------------+
1 row in set, 2 warnings (0.01 sec)

收到警告:

mysql> SHOW WARNINGS;
+---------+------+-----------------------------------------------------------------------+
| Level   | Code | Message                                                               |
+---------+------+-----------------------------------------------------------------------+
| Warning | 1292 | Incorrect datetime value: '1522933144' for column 'datetime' at row 1 |
| Warning | 1292 | Incorrect datetime value: '20180407571651'                            |
+---------+------+-----------------------------------------------------------------------+
2 rows in set (0.01 sec)

当我转换部分之间的第一个子句时,这是输出:

mysql> SELECT (NOW( ) - ( 86400 *30 ));
+--------------------------+
| (NOW( ) - ( 86400 *30 )) |
+--------------------------+
|           20180407571651 |
+--------------------------+
1 row in set (0.00 sec)

Between的第二个条款当然是当前日期。 所以解析后的查询应该成为:

SELECT * , from_unixtime( datetime ) FROM clues_rma_efficacy_triggers WHERE DATETIME BETWEEN 20180407571651 AND '2018-04-10 16:07:00' AND parent_key_id =89 AND parent_flag =0 LIMIT 200;

当然不是取结果。

mysql> SELECT * , from_unixtime( datetime ) FROM clues_rma_efficacy_triggers WHERE DATETIME BETWEEN 20180407571651 AND '2018-04-10 16:07:00' AND parent_key_id =89 AND parent_flag =0 LIMIT 200; 
Empty set, 1 warning (0.00 sec)

收到警告:

mysql> SHOW WARNINGS;                                                                                                                                                                          +---------+------+---------------------------------------------------------+
| Level   | Code | Message                                                 |
+---------+------+---------------------------------------------------------+
| Warning | 1292 | Truncated incorrect DOUBLE value: '2018-04-10 16:07:00' |
+---------+------+---------------------------------------------------------+
1 row in set (0.01 sec)

我很困惑第一个查询是如何工作的。 Where子句仅包含AND条件。它应该立即失败,因为在解析的查询中datetime子句不正确。 Verison输出:

mysql> SELECT VERSION();
+-----------------+
| VERSION()       |
+-----------------+
| 10.1.12-MariaDB |
+-----------------+
1 row in set (0.00 sec)

enter image description here

0 个答案:

没有答案