如果我有一个以数字开头的字符串,那么包含非数字字符,在MySQL中将此字符串转换为整数将转换字符串的第一部分,并且不表示它遇到任何问题!这很烦人。
例如:
SELECT CAST('123' AS UNSIGNED) AS WORKS,
CAST('123J45' AS UNSIGNED) AS SHOULDNT_WORK,
CAST('J123' AS UNSIGNED) AS DOESNT_WORK
返回:
+-------------+---------------+-------------+
| WORKS | SHOULDNT_WORK | DOESNT_WORK |
+-------------+---------------+-------------+
| 123 | 123 | 0 |
+-------------+---------------+-------------+
这对我没有任何意义,显然,123J45
不是数字,当然不等于123
。这是我的用例:
我有一个包含(一些格式错误的)邮政编码的字段。可能存在错误类型,缺少数据等,从我的角度来看,这是可以的。由于另一个表将Zip代码存储为整数,当我加入表时,我需要将字符串Zip代码转换为整数(如果我采用其他方式,我将不得不填充0
s)。但是,如果由于某种原因存在包含6023JZ1
的条目,则无法我希望将其解释为邮政编码06023
。 6023JZ1
映射到NULL
后,我感到非常高兴。不幸的是,由于上面讨论的问题,IF(CAST(zipcode AS UNSIGNED) <= 0, NULL, CAST(zipcode AS UNSIGNED))
不起作用。
我该如何控制?
答案 0 :(得分:0)
使用正则表达式:
select (case when val rlike '[0-9][0-9][0-9][0-9][0-9]' then cast(val as unsigned)
end)
许多人认为这是一个很好的功能,MySQL在进行此转换时不会自动产生错误。
答案 1 :(得分:0)
一个选项是测试字符串整个长度的数字字符0到9:
zipstr REGEXP '^[0-9]+$'
根据该布尔值的结果,您可以返回整数值,或者返回NULL。
SELECT IF(zipstr REGEXP '^[0-9]+$',zipstr+0,NULL) AS zipnum ...
(注意:添加零是对数字的隐式转换)
另一种选择是像你一样进行转换,然后将数值转换回字符,并与原始字符串进行比较,以返回布尔值:
CAST( zipstr+0 AS CHAR) = zipstr
(注意:第二种方法允许小数点,例如
CAST( '123.4'+0 AS CHAR ) = '123.4' => 1
如果您只是寻找一个有效的整数
,这可能是不可取的