函数/存储过程中的MySQL“错误的字符串值”错误

时间:2013-11-19 21:00:42

标签: mysql stored-procedures

我需要将以下语句的输出分配给MySQL FUNCTION或STORED PROCEDURE中的变量:

SELECT CAST(0xAAAAAAAAAAAFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AS CHAR(28));

我得到的就是这个:

  

错误代码:1366错误的字符串值:'\ x81 \ xEC \ x92 \ x01I \ x06 ...'代表第1行的'some_output'列

这很明显,但不知何故无法解决它。

我读到了所有其他CHARSET / COLLATION解决方案,但这对我没有帮助。

DELIMITER $$

CREATE DEFINER=`root`@`localhost` FUNCTION `function_name`(`some_input` VARCHAR(100)) RETURNS varchar(100) CHARSET utf8mb4
BEGIN
    DECLARE some_output CHAR(50) CHARSET utf8mb4;
    SET some_output = SELECT CAST(0xAAAAAAAAAAAFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF AS CHAR(28));
    RETURN some_output;
END

2 个答案:

答案 0 :(得分:0)

  

<强> Hexadecimal Literals
  ...在字符串上下文中,十六进制值的作用类似于二进制字符串......

你在找这样的东西吗?

CREATE FUNCTION function_name() RETURNS VARBINARY(28)
RETURN 0xAAAAAAAAAAAFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF;

这是 SQLFiddle 演示

答案 1 :(得分:0)

你在想一台电脑。数据库倾向于以比人们习惯的更人性化的方式概念化字符串。这曾经让我疯狂。

逻辑上合理的是,如果我有一个'字符串',那么我应该能够在每个字节位置存储从0x00到0xFF的任何内容,是吗?好吧,不,因为VARCHAR中的“CHAR”是“字符”(与“字节”不同)。

根据以下逻辑测试的结果,您可能会同意,数据库似乎对构成“字符串”的内容有不同的看法......

mysql> SELECT 'A' = 'a';
+-----------+
| 'A' = 'a' |
+-----------+
|         1 |
+-----------+
1 row in set (0.00 sec)

真?等等,在什么样的疯狂宇宙中才是真的?在具有排序规则的宇宙中确实如此,它确定了字符之间的排序和匹配(而不是字节)......并与字符集齐头并进,字符集将字符的位映射到字符的可视表示。在字符集中,并非每个可能的字节组合都是有效字符。

片刻的反思表明,0x41(“A”)被认为等于0x61(“a”)的世界不适用于二进制数据。

Incorrect string value: '\x81\xEC\x92\x01I\x06...'

UTF-8仅向0x7F及以下的值向后兼容良好的'ASCII',在给定的字节位置具有较大的值,表示从该字节位置开始的单个“字符”实际上也由一个或多个组成后续字节,这些字节的有效值由UTF-8的设计决定,其中多字节字符受到如下约束:

  

前导字节有两个或多个高阶1后跟一个0,而连续字节在高阶位都有'10'。

     

- http://en.wikipedia.org/wiki/UTF-8#Description

因此,字节0x81(10000001)不是UTF-8字符串中的有效字符,除非前面有一个值为&gt; = 0xC0的字节...所以你所拥有的是无效的UTF-8您尝试存储在根据定义需要有效UTF-8的结构中的字符串。

您正在寻找的结构是幸福的字符集和整理不知道VARBINARY,用于存储与算法相关的任意字节字符串,而不是VARCHAR,用于存储字符串。 (大概)与人类交流有关。