繁体   English   中英

如何将任意二进制数据插入VARCHAR列?

[英]How can I insert arbitrary binary data into a VARCHAR column?

我有一个使用utf8_general_ci归类的带有VARCHAR(100)列的MySQL表。

我可以看到该列包含任意字节序列的行(即,包含无效UTF8字符序列的数据),但是我无法弄清楚如何编写允许输入此类数据的UPDATE或INSERT语句。

例如,我尝试了以下方法:

UPDATE DataTable SET Data = CAST(BINARY(X'16d7a4fca7442dda3ad93c9a726597e4') AS CHAR(100)) WHERE Id = 1;

但是我得到了错误:

Incorrect string value: '\xFC\xA7D-\xDA:...' for column 'Data' at row 1

如何编写一个INSERT或UPDATE语句来绕过目标列的排序规则,从而允许我插入任意字节序列?

您是否考虑过使用Blob数据类型之一而不是varchar? 我相信这将减轻您的用例的痛苦。

编辑:或者,有MySQL支持的HEX和UNHEX函数。 十六进制采用str或数字参数,并以字符串形式返回参数的十六进制表示形式。 Unhex做相反的事情; 接受十六进制字符串并返回二进制字符串。

简短的答案是,不可能将具有无效UTF8字符的值插入声明为使用UTF8字符集的VARCHAR列中。

这就是MySQL的设计目标,即禁止无效值。 尝试执行此操作时,MySQL将返回错误或警告,或者(更宽容地?)在遇到的第一个无效字符处默默地截断所提供的值。

字符集问题更常见的变化是MySQL在不需要字符集转换时执行字符集转换。

但是,您要报告的问题是无效字符已插入UTF8列。 好像提供了latin1(ISO-8859)编码,并且需要字符集转换,但是没有执行。

至于解决此问题...我相信在早期版本的MySQL中是可能的。 我相信可以将值转换为BINARY,然后在CONVERT( ... USING UTF8)进行扭曲,而MySQL不会对字符集进行验证。 我不知道当前的MySQL连接器是否仍然可行。

如果可能的话,那是(IMO)连接器中的错误。

我能想到的解决该字符集检查/验证的唯一方法是,使MySQL服务器信任客户端,并确定不需要对该字符集进行检查。 (这也意味着MySQL服务器不会进行字符集转换,客户端躺在服务器上,客户端告诉服务器它正在提供有效的UTF8字符。

基本上,客户端将告诉服务器“嘿,服务器,我要发送UTF8字符编码”。

服务器说:“好的。因为我们匹配,所以我不会进行任何字符集转换。而且我只相信您发送的内容是有效的UTF8”。

然后客户调皮地嘲笑自己:“嘿,嘿,我撒谎了。我实际上是在发送无效的UTF8字符编码”。

而且我认为,使用旧式MySQL C API( mysql_stmt_preparemysql_stmt_execute )准备的语句,能够提供有效的UTF8编码作为字符串绑定参数的值,更有可能实现这种恶作剧。 (实际上,客户端有责任为绑定参数提供有效值。)

您应该预先对值进行base64编码,以便可以使用它生成有效的SQL:

UPDATE DataTable SET Data = from_base64('mybase64-encoded-representation-of-my-value') WHERE Id = 1;

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM