如果我运行查询,在 MySQL 上
SELECT * FROM table WHERE id = '1blah'
并且有一条 ID 为 1 的记录,查询实际上会返回该记录。我正在通过 Workbench 和 PHP/Doctrine 执行查询,得到相同的结果。
为什么 MySQL 会这样做?我在这里缺少一个更一般的数据库概念吗?语言/客户对此有什么作用吗?
最后,PostgreSQL 和 Oracle 会如何表现?
如果我运行查询,在 MySQL 上
SELECT * FROM table WHERE id = '1blah'
并且有一条 ID 为 1 的记录,查询实际上会返回该记录。我正在通过 Workbench 和 PHP/Doctrine 执行查询,得到相同的结果。
为什么 MySQL 会这样做?我在这里缺少一个更一般的数据库概念吗?语言/客户对此有什么作用吗?
最后,PostgreSQL 和 Oracle 会如何表现?
Postgres 和 Oracle 会(正确地)返回一个语法错误:
# select 1 = '1abc';
ERROR: invalid input syntax for integer: "1abc"
LINE 1: select 1 = '1abc';
MySQL 允许这样做,因为它进行隐式转换。可以将其视为可以追溯到其第一个版本的技术债务。它允许(例如)PHP 应用程序执行类似select * from foo where id = '1'
. 无论好坏。
如果你不喜欢这种行为,你可以通过让 MySQL 从 MySQL 5 开始以严格模式运行来禁用它。但这会破坏大多数 PHP 应用程序。
MySQL 默认以非严格模式运行,这就是您看到这种行为的原因。本质上,默认模式将进行转换以使用户的生活更轻松。不幸的是,我发现在尝试调试时它会让你的生活更加困难。
通过执行使 MySQL 表现得像传统的数据库服务器启用TRADITIONAL
模式SET sql_mode=TRADITIONAL;
这将启用数据检查、空值检查、除以零检查等。
正如 Denis 所说,如果您的 ID 是整数列,或者如果 ID 是文本(或文本变体)任何符合该条件的行,PostgreSQL 和 Oracle 将返回错误,这似乎是您所期望的,并且 IMO默认情况下应该发生什么。