CONCAT_WS 系统之间的行为差​​异

Difference in behavior on CONCAT_WS between systems

所以,这是一个简单的情况,但我想了解导致此问题的原因。我有以下代码(例如修改):

SELECT `Transactions`.*, CONCAT_WS(" ", `People`.`first_name`, `People`.`last_name`) AS full_name ...

在我的本地机器上我有:

使用该组合,以下代码可以正常工作。

在我的远程服务器上:

所以,我有一个部分使用数据 table 并且数据 table 使用服务器端处理来获取信息。在我的本地它正确显示信息,但在我的远程服务器上我总是得到一个空数组。所以我尝试在我的远程服务器上执行相同的 SQL 命令,但我得到了这个错误:

#1054 - Unknown column ' ' in 'field list'

我的 SQL 格式正确所以我认为问题可能与 CONCAT_WS 函数有关。

所以我决定修改为:

SELECT `Transactions`.*, CONCAT_WS(' ', `People`.`first_name`, `People`.`last_name`) AS full_name ...

我基本上将 CONCAT_WS(" ", 更改为 CONCAT_WS(' ',,并且代码按预期运行。

我不确定这是否会以某种方式影响,但这是 MySQL 对 CONCAT_WS 或其他使用要求的更改吗?

如果我在别处用单引号可以吗?

我建议你 运行 在两个系统上都这样做:

SELECT @@sql_mode;

您会发现在您的 8.0 服务器上,sql 模式包括模式 ANSIANSI_QUOTES

解释:

双引号在 MySQL 中有不同的含义,具体取决于哪个 sql 模式有效。

默认情况下,双引号与单引号相同:它们分隔字符串文字。

如果 sql 模式是 ANSIANSI_QUOTES,则双引号分隔标识符,作用类似于反引号。

因此,相同的代码在不同的 MySQL 实例中可能表现不同。这与 5.7 和 8.0 之间的差异无关,因为 sql 模式在这两个版本上的行为相同。默认情况下,这两个版本都不启用 ANSIANSI_QUOTES 模式,因此您或其他人必须在您的 8.0 服务器上启用该模式。

这就是为什么在这个表达式中:

CONCAT_WS(" ", ...)

第一个参数 " " 在一个服务器上被视为字符串文字,在另一台服务器上被视为名称为 的列(这是合法的 SQL, 即使它很奇怪).

最安全的做法是始终使用单引号来分隔字符串文字,并始终使用反引号来分隔标识符。

永远不要在 MySQL 中对任何一种情况使用双引号,因为如果有人更改 sql 模式,您在 SQL 查询中使用双引号的代码将会中断。