在MySQL

时间:2018-10-06 09:47:45

标签: mysql sql node.js

我正在将带有InnoDB的MySQL 8与带有mysql2驱动程序的节点服务器一起使用。

我的桌子如下:

CREATE TABLE IF NOT EXISTS users(
      id VARCHAR(36) NOT NULL,
      name VARCHAR(32) NOT NULL,
      email VARCHAR(255) NOT NULL,
      ...
      PRIMARY KEY (id) 
     )

我不使用自动递增,作为VARCHAR ID,我使用基于时间的UUID。

如果我现在执行SELECT查询:

SELECT * FROM users where id = 'some valid id';

我得到了预期的结果。

如果我这样做:

SELECT * FROM users where id = '0';

我什么也没得到,因为表中没有id的值为'0'。

但是,如果我这样做:

SELECT * FROM users where id = 0;

我得到了最后插入的行,它当然有一个有效的VARCHAR id,它不同于0。

由于我的节点服务器有时会在http查询中将undefined解释为0,因此偶然在我的节点服务器上发生了此行为。 因此,我可以轻松避免在查询中插入0(我现在要做什么),但是我想了解为什么会这样。

1 个答案:

答案 0 :(得分:2)

您的idvarchar(),因此此比较:

WHERE id = 0

需要类型转换。

根据SQL中的转换规则,id被转换为字符串。现在,在许多数据库中,如果无法将id的任何值转换为数字,则会出现错误。

但是,MySQL支持隐式转换没有错误。 (您可以在documentation中了解有关这种转换的信息。)这会将所有前导数字转换为数字-忽略其余的数字。如果没有前导数字,则该值为零。因此,所有这些在MySQL中都是正确的:

  • 'a' = 0
  • '0a' = 0'
  • 'anything but 0!' = 0

这个故事有两种寓意。

  1. 如果您确实希望id是一个数字,请使用数字数据类型(intbigintdecimal)。
  2. 请勿在比较中混合类型。