[英]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语句来绕过目标列的排序规则,从而允许我插入任意字节序列?
简短的答案是,不可能将具有无效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_prepare
, mysql_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.