为什么MariaDB(MySQL)将数字文字视为字符串?

时间:2020-06-02 17:39:29

标签: mysql mariadb sqldatatypes

今天让我和我的同事感到有些奇怪。如果我们这样做:

select id from table

其中idinteger,则结果集中包含ID的整数。一切都很好。但是,当我们这样做时:

select 1

然后结果集包含字符串"1"。导致这种情况的实际情况更加复杂,涉及ifnull(),但这是重现此问题的最简单方法。

如果需要的话,我们正在使用NodeJS(+ Typescript)和TypeORM。我记得在PHP中也注意到类似的事情,但是由于PHP无论如何对类型都很松懈,所以我不太在意。但是,这次我们将数据作为JSON传递到外部系统,因此现在我们需要添加parseInt()才能将字符串类型的数字转换回实际数字。

但是-wtf?为什么会这样?

2 个答案:

答案 0 :(得分:0)

WHERE id = 123      -- fine
WHERE id = "123"    -- also fine; the string is converted to a number
WHERE text = "123"  -- also fine (assuming `text` is VARCHAR or TEXT)
WHERE text = 123    -- inefficient because it converts each text to numeric

许多API将值“绑定”到查询中。他们中的许多人盲目地引用事物,而不管目标是什么。请注意,上述情况表示引号始终有效。

所以,我认为这就是您问的“为什么”。

而且,正如您所说,PHP,Perl和其他解释型语言在这里占据了主导地位。

答案 1 :(得分:0)

我找到了答案。

事实证明,MySQL将数字文字解释为64位整数。在执行CAST(xxx as integer)时,它也将其视为64位整数(您不能在此处指定tinyint)等。因此,当它到达NodeJS时,它带有{{ 1}}。但是,如果您直接选择一个DB列,那么您将获得一个更合理的Int64或其他任何内容。

第二部分毕竟隐藏在MySQL客户端中。默认的Int32 NPM软件包所做的是检查名为mysql的连接设置,默认情况下为bigNumberStrings。如果为真,则将64位整数保留为字符串。原因很明显-Javascript的true类型是一个64位浮点值,并且小于64位整数。因此,将其保留为字符串可在所有情况下保持保真度。

另一方面,如果number,它将尝试将值转换为bigNumberStrings=false,并且只有太大时才将其保留为字符串。很好,但并不总是一致的-小心处理。

我必须考虑我要选择哪个选项。