2011-11-29 32 views
1

我查询的INT列一个字符串,像这样:MySQL的意外返回结果为 “WHERE integer_column = 'STRING_VALUE'”

SELECT id 
FROM (`navigation_links`) 
WHERE `navigation_links`.`navigation_link_id` = 'anyRandomString' 

(原来,这是由意外)

  • 预期的结果:0,因为navigation_link_idINT
  • 实际结果:这好像又回到每一行,其0

这将返回完全相反的:

SELECT id 
FROM (`navigation_links`) 
WHERE `navigation_links`.`navigation_link_id` != 'anyRandomString' 

下面是表,剥离下来:

CREATE TABLE `navigation_links` (
    `id` INT(10) UNSIGNED NOT NULL AUTO_INCREMENT, 
    `navigation_link_id` INT(10) UNSIGNED NULL DEFAULT '0', 
    `navigation_group_id` INT(10) UNSIGNED NULL DEFAULT '0', 
    PRIMARY KEY (`id`) 
) 

任何想法,这是怎么一回事?

回答

3

当比较不同类型的值时,MySQL将尝试convert这样的值之一,因此可以进行比较。在字符串和数字的情况下,MySQL将通过将任何前导数字解释为数字来转换字符串。没有前导数字对应于0的数值,这在一些方面是有意义的:

  • 前导零通常可以被丢弃; '042'与'42'相同。因此'0'和''是相同的。
  • 当数字串转换为数字,该号码的初始值是0。该字符串被遍历,加入的数字的数量和由碱增殖:

    n = 0 
    while str[i] is a digit character: 
        n += str[i] as a digit 
        ++i 
    return n 
    

    如果有没有数字字符,数值为0.

  • 空字符串没有任何内容,所以在以无数字开头的字符串开始处的数字字符串是空的。在这种思维方式下,NULL也可以是没有将前导数字解释为数字的字符串的值。这后一个选项并没有被MySQL开发者选中,可能使实现稍微简单一些。

+0

我明白了,所以在每个“数字”被选中之后,它会归结为“0”,然后呢?我注意到'where int ='3x''被转换为'3',但是'where int ='x3''被转换为'0'。我想这种转换有时候很有意义,但我对这种行为感到惊讶。 –

+0

@Madmartigan:请注意只有前导数字才会被转换,而不是第一个连续的数字子串。这与C函数atoi和strtol的行为是一样的。 MySQL可能会使用其中的一个(快速浏览源代码会告诉你这是否是这样)。您可以使用'CAST'和'CONVERT'函数来查看MySQL将字符串转换为什么数字。 – outis