【问题标题】:Difference in behavior on CONCAT_WS between systems系统之间 CONCAT_WS 上的行为差异
【发布时间】:2021-04-23 05:07:49
【问题描述】:

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

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

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

  • Windows 10
  • Apache 2.4.25
  • PHP 7.4.11
  • MySQL 5.7.25

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

在我拥有的远程服务器上:

  • Ubuntu 20.04.1 LTS
  • Apache 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 或其他什么的要求的变化吗?

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

【问题讨论】:

    标签: mysql concat-ws


    【解决方案1】:

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

    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 查询中使用双引号的代码将会中断。

    【讨论】:

    • 太好了,解决了。事实上,8.0 是一个 DigitalOcean 托管数据库服务器,所以他们添加了这些参数。我的本地服务器没有定义它们。感谢您的明确答复。
    猜你喜欢
    • 1970-01-01
    • 2011-07-30
    • 1970-01-01
    • 1970-01-01
    • 2011-08-15
    • 1970-01-01
    • 1970-01-01
    • 2018-06-21
    • 2012-06-25
    相关资源
    最近更新 更多