严格模式以避免类型转换

时间:2013-09-03 10:24:11

标签: mysql

是否有任何sql模式会返回错误而不是隐式将字符串转换为整数?

mysql> select * from todel ;
+------+--------+
| id   | name   |
+------+--------+
|    1 | abc    |
|    2 | xyz    |
|    0 | ABCxyz |
+------+--------+
3 rows in set (0.00 sec)

我期待错误消息而不是id为0的行

mysql> select * from todel where id = 'abc';
+------+--------+
| id   | name   |
+------+--------+
|    0 | ABCxyz |
+------+--------+
1 row in set, 1 warning (0.00 sec)

mysql> show warnings;
+---------+------+-----------------------------------------+
| Level   | Code | Message                                 |
+---------+------+-----------------------------------------+
| Warning | 1292 | Truncated incorrect DOUBLE value: 'abc' |
+---------+------+-----------------------------------------+
1 row in set (0.01 sec)

2 个答案:

答案 0 :(得分:3)

我了解您的疑虑,但正是由于这个原因,您永远不会将ID设置为0。从长远来看,我认为你应该在行为之前重新考虑你的表行,这在理想情况下不是问题。我没有通过一些搜索找到与此相关的任何内容,这可能是因为它可能不是问题,除非你把它做成一个。

除此之外,你可以读取相关的列数据,并在php / whatev中进行相应的操作。从COLUMNS中的information_schema表中,您可以按TABLE_SCHEMA(数据库),TABLE_NAMECOLUMN_NAME进行过滤,以获得DATATYPE(双倍)。如果您要更改的列具有某个DATATYPE,请在运行MySQL查询之前让脚本出错。

另一种方法是在解析之前转换输入:

if ( ! is_numeric($id))
    $id = 'NULL';

为防止INSERTUPDATE不正确,您已have that mode


最后,我无法想出许多实用的方法,你所使用的这种严格模式会使MySQL用户受益。

答案 1 :(得分:2)

您可以使用STRICT_ALL_TABLES sql模式:

set @@GLOBAL.sql_mode  = "STRICT_ALL_TABLES";
set @@SESSION.sql_mode = "STRICT_ALL_TABLES";

然而,它仅适用于写操作:

MariaDB [(none)]> insert into test.test values ( "abc", "lol" );
--------------
insert into test.test values ( "abc", "lol" )
--------------

ERROR 1366 (22007): Incorrect integer value: 'abc' for column 'id' at row 1

没有这样的事情可以禁用读取查询的隐式转换;相反,你可以检查是否有警告,如果是,只需释放结果,中止声明,并将这些警告威胁为错误。