【问题标题】:Odd behavior of UPPER in select选择中 UPPER 的奇怪行为
【发布时间】:2013-04-27 16:55:32
【问题描述】:

我正在尝试在 MySQL 选择中操作一些字符串,但 UPPER 函数似乎有一些奇怪的行为。

我正在尝试返回单词的第一个字母(以空格分隔)并将其转换为大写。但是,如果我在单个返回的字母上使用 UPPER,我会得到一个空白,而如果我在得到第一个字母之前对整个单词使用 UPPER,我会得到第一个字母。

将 SQL 精简到我想出的这个测试 SQL 的最低限度:-

SELECT 
    'verbatim h', 
    SUBSTRING(SUBSTRING_INDEX(SUBSTRING_INDEX(CONCAT(' ','verbatim h',' '), ' ', 2), ' ', -1), 1, 1),
    UPPER(SUBSTRING(SUBSTRING_INDEX(SUBSTRING_INDEX(CONCAT(' ','verbatim h',' '), ' ', 2), ' ', -1), 1, 1)),
    SUBSTRING(UPPER(SUBSTRING_INDEX(SUBSTRING_INDEX(CONCAT(' ','verbatim h',' '), ' ', 2), ' ', -1)), 1, 1)

这是获取字符串'verbatim h',在两端连接空格,然后获取第一个和第二个空格之间的字符串(因此它将得到verbatim)。

第一列是完整的字符串,第二列是第一个单词的第一个字母,第三列是第一个单词的大写字母,第四列是第一个单词的第一个字母转换为大写。

我认为第 3 列和第 4 列应该具有相同的值(唯一的区别是一个在抓取第一个字母之前将第一个单词转换为大写,而另一个抓取第一个字母然后将其转换为大写),但是相反,一个包含字母 V,正如我所期望的,而另一个包含空白。

如果我修改上面得到结果字符的 HEX 值,空白的是一个 1 的字符串,十六进制值为 00,而 V 是一个十六进制值 56。

有什么建议吗?我错过了什么明显的东西吗?

【问题讨论】:

  • 对于那些将来发现这个问题的人来说,它似乎已经为 MySQL 5.6 修复了。

标签: mysql uppercase


【解决方案1】:

字符串变成二进制字符串。对于这些,您不能使用LOWERUPPER,如mysql reference docu 中所述

那么怎么解决呢?

像这样使用convert 函数:

SELECT 
    'verbatim h', 
    SUBSTRING(SUBSTRING_INDEX(SUBSTRING_INDEX(CONCAT(' ','verbatim h',' '), ' ', 2), ' ', -1), 1, 1) AS c1,
    UPPER(CONVERT((SUBSTRING(SUBSTRING_INDEX(SUBSTRING_INDEX(CONCAT(' ','verbatim h',' '), ' ', 2), ' ', -1), 1, 1)) USING latin1)) AS c1_upper;

这是sqlfiddle

【讨论】:

  • 有趣。我认为您是对的,但不确定为什么 MySQL 决定将针对字符串的 SUBSTRING 的结果视为二进制。特别是如果您使用示例 SQL 作为子选择,然后在第二列上执行 UPPER,它会给出正确的结果。
  • 我有点奇怪,真的。我没有深入了解 mysql 字符串函数的逻辑以及它们何时以二进制字符串返回。我想这是针对单个字符串的“优化”。
  • 嗯,不太确定是否进行了更多调查。更改 SUBSTRING 以获取前 2 个字符,在第一个字符上使用 UPPER 会返回“V”(十六进制 5600) - 同样,如果将其更改为前 3 个字符,它会将前 2 个字符带回大写,并且在第 3 位。看起来它正在破坏字符串的最后一个字符。
猜你喜欢
  • 2019-12-03
  • 1970-01-01
  • 1970-01-01
  • 2013-01-29
  • 2014-05-28
  • 1970-01-01
  • 2011-10-24
  • 1970-01-01
  • 2011-08-19
相关资源
最近更新 更多