需要使用临时变量来使SUBSTRING_INDEX的REPLACE工作

时间:2016-04-19 19:19:08

标签: mysql substring

我们在许多Debian服务器上运行MySQL 5.5.47。在其中一些,我们看到以下奇怪的行为:

mysql> set @TKEY:='ARDARD:fae590c4.ffa2.11e5.a318.0cc47a39aeb4-1460351116';  
mysql> select replace(substring_index(substring_index(@TKEY,':',-1),'-',1), '.','-') as guid;
+--------------------------------------+
| guid                                 |
+--------------------------------------+
| fae5a2.1--0cc47a 9ae47a 9aeb4a 9aeb4 |
+--------------------------------------+

这应该提取@TKEY的中间部分(:-之间)并用连字符替换所有句点。这些空间来自哪里?结果的其他部分似乎混乱:9aeb4已被复制,a2.1已向左移动。

如果我将substring_index分配给中间变量,则不会发生这种情况。

mysql> set @temp = substring_index(substring_index(@TKEY,':',-1),'-',1);
mysql> select replace(@temp, '.', '-') as guid;
+--------------------------------------+
| guid                                 |
+--------------------------------------+
| fae590c4-ffa2-11e5-a318-0cc47a39aeb4 |
+--------------------------------------+

这只发生在我们的生产服务器上。我无法在我们的开发服务器或sqlfiddle上重现它。我比较了所有服务器变量,并没有看起来应该影响字符串函数行为的差异(最初在字符集和整理变量方面存在一些差异,但我更改了dev服务器以匹配生产服务器并仍然无法不要复制错误。

在运行MySQL 5.5.41的另一台生产服务器上,我得到了一个稍微不同的错误结果:

mysql> select replace(substring_index(substring_index(@TKEY,':',-1),'-',1), '.','-') as guid;
+--------------------------------------+
| guid                                 |
+--------------------------------------+
| fae590c4-ffa2-11e5-a318-0cc47a 9aeb4 |
+--------------------------------------+

这是正确的,除了有一个空格代替最后3

任何人都能解释一下吗?这只是一个MySQL错误吗?我在bugs.mysql.com找不到任何东西。

1 个答案:

答案 0 :(得分:3)

这似乎是MySQL 5.6.5中修复的错误。关于LOWER(SUBSTRING_INDEX(...)),有一个类似的错误报告。评论已结束:

  

在5.6.5更改日志中注明。

     

SUBSTRING_INDEX()的结果可能在使用时丢失了字符   作为转换函数的参数,例如LOWER()。

我怀疑潜在的原因是指针滥用导致缓冲区溢出和未定义的行为。希望我没有破坏服务器中任何长期存储器。