1

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

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

在我的本地机器上,我有:

  • 视窗 10
  • 阿帕奇 2.4.25
  • PHP 7.4.11
  • MySQL 5.7.25

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

在远程服务器上,我有:

  • Ubuntu 20.04.1 LTS
  • 阿帕奇 2.4.41
  • PHP 7.4.3
  • MySQL 8.0.19

所以,我有一个部分使用数据表,数据表使用服务器端处理来获取信息。在我的本地,它正确显示了信息,但在我的远程服务器上,我总是得到一个空数组。所以我尝试在我的远程服务器中执行相同的 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还是其他方面的变化?

如果我在其他地方使用单引号可以吗?

4

1 回答 1

2

我建议你在两个系统上运行它:

SELECT @@sql_mode;

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

解释:

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

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

如果 sql 模式是ANSIor ANSI_QUOTES,则双引号分隔标识符,就像反引号一样。

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

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

CONCAT_WS(" ", ...)

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

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

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

于 2021-01-18T21:55:06.630 回答