[英]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.