簡體   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