SQL 資料庫將十六進位值儲存為原始位元組、編碼字串或 varbinary 欄位,而在 SQL 中將十六進位轉換為文字意味著使用引擎的內建函式將該位元組序列轉回字元。MySQL 提供 UNHEX() 並將其與 CONVERT(... USING utf8mb4) 搭配使用;SQL Server 將 varbinary 以 0x 前綴的十六進位字串傳回,您可將其重新轉型為 varchar;Kingbase 及其他中國引擎分支則依賴 DECODE() 結合明確的 CONVERT 字元集;PostgreSQL 通常透過 bytea 中介層使用 encode() 與 decode()。每種做法都有細微的失敗模式:預設的替換解碼器在位元組損壞時可能會代入 U+FFFD 字元,varchar 目標可能會悄悄截斷,而連線定序與來源字串不符時則可能傳回亂碼(mojibake)。一款以 fatal 模式解碼 UTF-8 的瀏覽器版 Hex to Text Converter 是可靠的第二意見來源——可將 SQL 輸出以連續十六進位、空白分隔的十六進位或 0xNN 詞元貼上,工具要嘛傳回精確文字,要嘛拒絕解碼,絕不會回傳部分替換字串。

跨引擎將十六進位轉換為文字的 SQL 函式
數種 SQL 方言搭載了不同的十六進位轉文字基本函式,了解哪個可用會影響您將儲存資料讀回字元的方式。MySQL 的 UNHEX() 接受十六進位字面值(例如 UNHEX('48656C6C6F'))並傳回對應的位元組;將其與 CONVERT(... USING utf8mb4) 結合,等於告訴伺服器將這些位元組視為 UTF-8,而非連線的預設字元集。SQL Server 沒有直接的 UNHEX,但 SELECT CAST(0x48656C6C6F AS varchar(50)) 這類運算式使用相同的 0x 字面值語法來宣告內嵌十六進位位元組,再將其投影為字串,而 CONVERT(varchar(100), 0x48656C6C6F) 則透過轉換函式達到相同目的。PostgreSQL 的方向相反——encode() 將文字轉為十六進位,decode() 將十六進位轉為位元組——因此整個往返過程看起來像 convert_from(decode('48656C6C6F', 'hex'), 'UTF8')。Kingbase 採用 DECODE 風格的 API,其中 DECODE('E4BDA0E5A5BD', 'hex') 會產生原始位元組,接著必須以明確的 'UTF8' 目標字元集進行 CONVERT 才能得到「你好」。這四種做法涵蓋了絕大多數 SQL 十六進位轉文字的問題,它們之間的差異也解釋了當 SQL Server 讀取 MySQL 匯出檔時,多數「在我這台機器上可以跑」回報的成因。
| SQL 引擎 | 主要的十六進位轉文字函式 | 必要的字元集步驟 | 預設輸出類型 | 典型失敗模式 |
|---|---|---|---|---|
| MySQL | UNHEX('hex') | CONVERT(... USING utf8mb4) | 先 varbinary 再字串 | 傳回二進位;連線字元集不符會顯示亂碼 |
| SQL Server | CAST(0x... AS varchar) | 透過欄位定序隱含進行 | varchar | 在定序邊界處出現替換字元或截斷 |
| PostgreSQL | decode('hex', 'hex') | convert_from(..., 'UTF8') | text | 對非十六進位輸入報錯;沒有替換後援機制 |
| Kingbase | DECODE('hex', 'hex') | CONVERT(..., 'UTF8') | varchar | 來源字元集必須與位元組相符,否則輸出錯誤 |
為何僅靠 SQL 轉換可能產生誤導
看起來成功的 SQL 結果並不代表解碼正確,因為每個引擎處理損壞 UTF-8 的方式不同,而可見的輸出可能掩蓋了真正的損害。MySQL 的 UNHEX() 無論這些位元組是否構成有效的 UTF-8,都會直接傳回二進位位元組;若接著使用 CONVERT ... utf8mb4 但未啟用 fatal 模式,伺服器可能會將截斷的多位元組序列、編碼後的代理項與超長形式替換為 U+FFFD,留下一個看起來像資料、實際卻是局部重建的字串。SQL Server 從 varbinary 到 varchar 的 CAST 會使用欄位或運算式的定序,因此一個以 UTF-8 編碼的十六進位承載若進入 Latin1 欄位,會以亂碼呈現而非報錯——位元組在技術上確實被轉換了,但意思卻完全不同。PostgreSQL 的 convert_from 會在無效 UTF-8 時拋出例外,這是四者中最安全的行為,但其錯誤訊息往往隱藏了精確的位元組位移,迫使您必須將輸入對半切開來定位問題。Kingbase 的 DECODE 路徑在目標字元集較為寬鬆時,會繼承與 MySQL 相同的替換字元風險。綜觀所有這些引擎,更深層的問題在於 SQL 引擎對「有效 UTF-8」的定義可能比RFC 3629 寬鬆,因此一段您的 SQL 查詢能順利轉成文字的十六進位字串,仍可能包含嚴格解碼器會拒絕的位元組。
在嚴格 UTF-8 瀏覽器工具中驗證 SQL 十六進位輸出
當您需要確定某個十六進位值究竟應該顯示為何時,請將 SQL 輸出貼入 Hex to Text Converter,讓 fatal UTF-8 解碼器擔任最終裁判。此工具在本機目前的瀏覽器分頁中執行,因此資料庫內容不會離開您的機器,且它接受 SQL 引擎常見的三種十六進位格式。
- 執行會傳回十六進位的 SQL 查詢(例如 SELECT HEX(column) FROM table,或傳回 varbinary 為 0x 字串的 SELECT),複製所得的十六進位字串且不要重新排版。
- 開啟 Hex to Text Converter,將十六進位貼入輸入欄位——連續配對(如 48656C6C6F)、以 ASCII 空白分隔的群組(如 48 65 6c 6c 6f)、或明確的 0xNN 位元組詞元(如 0x48 0x65 0x6C 0x6C 0x6F),只要啟用對應的語法選項皆可使用。
- 若您的 SQL 輸出在位元組群組之間包含空格、Tab 或換行,請切換 ASCII 空白分隔選項;若字串以 0x 開頭(SQL Server 的 varbinary 轉型常產生這種形式),請切換 0x 前綴選項。
- 點擊 Decode 並讀取結果文字或錯誤訊息。Fatal 模式意味著奇數 nibble、孤立的續接位元組、截斷的三位元組序列、編碼後的代理項,或大於 U+10FFFF 的數值都會讓解碼完全停止——不會回傳替換字元,也不會回傳局部前綴。
- 若解碼成功,可使用複製按鈕從唯讀欄位複製文字(瀏覽器會要求一次剪貼簿權限),或在權限被拒時手動選取。
如需更深入地了解如何在輸入階段就揪出損壞的位元組,請參閱 如何在沒有靜默錯誤的情況下將十六進位字串轉換為文字。
SQL 查詢輸出的純十六進位 vs 0xNN 格式
SQL Server 的 CAST(0x48656C6C6F AS varchar(50)) 直接傳回位元組本身,而非十六進位字串,但一旦將該值包進會傳回字串的函式,結果常會以 0x 前綴的十六進位字面值印出——這是 Hex to Text Converter 中第二種被接受的語法。啟用 0x 選項時,解析器會切換為嚴格模式,要求每個詞元都必須剛好是 0xNN 格式——不能是 0x041、不能是 0x410x42、詞元之間不能有逗號,也不能在同一字串中與無前綴的群組混用。另一方面,MySQL 的 HEX(column) 會輸出不帶 0x 前綴的純十六進位字串,因此同樣的輸入會以 48656C6C6F 貼上,並在純模式(plain mode)下解碼,該模式的唯一限制是每組必須有偶數個十六進位數字。PostgreSQL 的 encode(bytes, 'hex') 屬於同一純模式陣營,Kingbase 的 DECODE 來源字串同樣也是純格式。了解應啟用哪種模式很重要,因為當 0x 模式為開啟但其餘輸入不符時,解析器會拒絕任何它所看到的前綴;而停用前綴時則會直接拒絕 0x 輸入,而非靜默地將其移除,此一行為遵循 MDN 上所記載的 WHATWG Encoding Standard 解碼器契約。
將常見的 SQL 十六進位字串讀為 UTF-8
SQL 的十六進位值通常看起來不透明,但每一對十六進位數字其實就只是一個位元組,而大多數工作資料都是 ASCII,因此您通常能預測解碼器應該傳回什麼。以一段您在 MySQL UNHEX 範例中可能會看到的十六進位字串為例:48656C6C6F20576F726C64。拆成位元組配對並從 ASCII 表讀取——0x48 是 'H'、0x65 是 'e'、0x6C 是 'l'、0x6C 是 'l'、0x6F 是 'o'、0x20 是空格、0x57 是 'W'、0x6F 是 'o'、0x72 是 'r'、0x6C 是 'l'、0x64 是 'd'。整段序列因此讀作 "Hello World"——11 個位元組、11 個字元,沒有涉及多位元組序列。更值得玩味的情況是 E4BDA0E5A5BD,也就是 Kingbase DECODE 範例中「你好」的 UTF-8 編碼:0xE4 0xBD 0xA0 是 U+4F60(你)的三位元組形式,0xE5 0xA5 0xBD 則是 U+597D(好)的三位元組形式。將其中任一字串貼入啟用 ASCII 空白分隔選項的 Hex to Text Converter,即可得到預期文字;而若貼上刻意損壞的版本(例如 E4BD,一個被截斷的三位元組序列),則會回傳錯誤而非替換字元——這證明了 SQL 位元組在傳輸過程中並未保持完整。
SQL 十六進位解碼為替換字元的情境
如果您曾在 SQL 輸出中看過一個帶問號的黑色菱形,您其實是目睹了資料庫悄悄改寫損壞位元組的過程。替換字元最常出現在 UTF-8 字串經由字元集較窄的欄位或連線往返時——例如 Latin1、ASCII 或部分支援多位元組的定序——因為目的端引擎不知道該如何處理它無法表示的高位元組。它也會在十六進位字面值包含無效 UTF-8 片段時出現,例如孤立的續接位元組 0x80,或像 C0 AF 這種超長形式(理應編碼為 U+002F,卻使用了兩個禁止的位元組)。瀏覽器端的 Hex to Text Converter 透過依照 RFC 3629 將 WHATWG TextDecoder 設定為 fatal 模式,完全避免了這種結果:無效位元組、截斷序列、編碼後的代理項,以及大於 U+10FFFF 的數值,都會產生硬錯誤且不輸出任何內容,因此同一段十六進位字串在寬鬆的 SQL 主控台中可能印成 "Hello��World",要嘛在嚴格模式下乾淨地解碼為 "HelloWorld",要嘛完全拒絕解碼。重點就在於這種不對稱——靜默替換雖然方便隨意瀏覽,卻會掩蓋資料損毀,而嚴格的瀏覽器檢查就是釐清您究竟碰上哪種情況的最便宜手段。
Related Hex Workflows From SQL Output
A SQL query rarely stops at hex-to-text, and a few adjacent paths come up often enough to flag here. When the SQL output is a formatted memory dump with addresses such as 00000000 48 65 6c 6c 6f ... rather than a clean byte column, extract only the byte column using a trusted workflow before pasting it, because the tool does not strip addresses or skip whitespace beyond the five ASCII characters it knows about. When the SQL column stores raw binary rather than hexadecimal — for instance a BLOB payload extracted with CAST(column AS varchar(MAX)) — use Binary to Text instead, since hex and binary are different notations and the parser will reject binary input. When the SQL output is Base64 rather than hex, route it through Base64 Encode / Decode first and then convert the resulting bytes to hex if needed. None of these paths upload data to a server; each tool runs locally in the current browser tab and shares the same fatal-UTF-8 strictness, so the verification property you build up with the Hex to Text Converter carries over to every other step.
If you're weighing options, Base64 to Hex Free No Sign Up: Convert in Browser covers this in detail.