我需要将以下语句的输出分配给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
答案 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'。
因此,字节0x81(10000001)不是UTF-8字符串中的有效字符,除非前面有一个值为&gt; = 0xC0的字节...所以你所拥有的是无效的UTF-8您尝试存储在根据定义需要有效UTF-8的结构中的字符串。
您正在寻找的结构是幸福的字符集和整理不知道VARBINARY,用于存储与算法相关的任意字节字符串,而不是VARCHAR,用于存储字符串。 (大概)与人类交流有关。