mysql自动将字符串转换为整数

时间:2014-07-15 15:20:56

标签: php mysql casting doctrine-orm implicit-conversion

我的问题是一般问题:

学说对待

$entitity->getTest()->clear();

进入这个SQL查询:

DELETE FROM test WHERE test_id = '6'

- > test_id是数据库中的一个整数,mysql自动转换值,使其工作。 但正确的查询是:

    DELETE FROM test WHERE test_id = 6

我在这里找到了一些Diskussions:

stackoverflow.com/questions/21762075/mysql-automatically-cast-convert-a-string-to-a-number

code.openark.org/blog/mysql/implicit-casting-you-dont-want-to-see-around

mysql doc说:

http://dev.mysql.com/doc/refman/5.5/en/type-conversion.html

  

"以下规则描述了比较操作如何进行转换" (..)在所有其他情况下,参数被比较为浮点(实数)。

文档还说明了它的问题:

  

使用浮点数(或转换为浮点数的值)的比较是近似值,因为这些数字是不精确的。这可能会导致结果不一致

那么为什么教条主义和dbal行为如此呢?对于带有整数的表,这不是问题吗?只有bigint?

另见:

http://www.cubrid.org/cubrid_implicit_type_conversion

- >它告诉我这不是问题。

所以我的问题是:查询int_val =' 1' (字符串)没什么大不了的,或者这可能是危险的。如果这很危险,那么在这里匆忙提出一个设计问题吗?

2 个答案:

答案 0 :(得分:0)

来自文档:

  
      
  • 如果一个或两个参数都是NULL,则比较结果为NULL,但NULL - 安全<=>等式比较运算符除外。对于   NULL <=> NULL,结果是真的。无需转换。

  •   
  • 如果比较操作中的两个参数都是字符串,则将它们作为字符串进行比较。

  •   
  • 如果两个参数都是整数,则将它们作为整数进行比较。

  •   
  • 如果不与数字进行比较,十六进制值将被视为二进制字符串。

  •   
  • 如果其中一个参数是TIMESTAMPDATETIME列而另一个参数是常量,则该常量将转换为时间戳   在进行比较之前。这样做更多   ODBC友好。请注意,IN()的参数不会执行此操作!   为安全起见,请始终使用完整的日期时间,日期或时间字符串   做比较。例如,在使用时获得最佳效果   BETWEEN包含日期或时间值,请使用CAST()显式转换   值到所需的数据类型。

  •   
  • 如果其中一个参数是十进制值,则比较取决于另一个参数。如果将参数作为十进制值进行比较   另一个参数是十进制或整数值,或者是浮点数   如果另一个参数是浮点值,则返回值。

  •   
  • 在所有其他情况下,将参数作为浮点(实数)进行比较。

  •   

您的案件属于“所有其他案件”。

该字符串将转换为FLOAT,然后与您的int_val进行比较。

如果字符串转换得很好(像'1''0.1''1E5'这样的值),结果值将与整数进行比较。

如果不是(比如传递类似'1235xxx'的值),可能的前导数字将被转换为浮点数(0,如果没有),其余数字将被截断。此外,还会生成警告。

在字符串中传递id的原因可能是您的id不一定必须是整数。它也可以是字符串或日期。

ORM可能有一个生成DELETE查询的通用代码,可用于任何数据类型。

答案 1 :(得分:0)

  

当运算符与不同类型的操作数一起使用时,会发生类型转换以使操作数兼容。某些转换是隐式发生的。例如,MySQL会根据需要自动将数字转换为字符串,反之亦然。 Reference

这在选择/插入/更新时也适用,使用列类型作为参考。

因此,如果您执行SELECT * FROM users WHERE balance = '1234'并且列balance的类型为DECIMAL (6,2),则隐含以下内容。

mysql> SELECT CONVERT ('1234', DECIMAL (6,2));
+---------------------------------+
| CONVERT ('1234', DECIMAL (6,2)) |
+---------------------------------+
|                         1234.00 |
+---------------------------------+
1 row in set (0.00 sec)

对于那些无法转换的值,您将始终拥有默认值。

mysql> SELECT CONVERT ('test', DECIMAL (6,2));
+---------------------------------+
| CONVERT ('test', DECIMAL (6,2)) |
+---------------------------------+
|                            0.00 |
+---------------------------------+
1 row in set, 1 warning (0.00 sec)

所以不,没有涉及漏洞(至少在MySQL方面)。