选择十六进制/字符转换

时间:2018-07-19 15:44:19

标签: sql-server tsql encoding sql-server-2012 hex

我在SQL数据库中以以下格式存储了一些数据,我希望将其转换为可读的字符串:

540045005300540049004E00470031003200330034

我想运行某种SELECT语句返回应该为TESTING1234的文本

它看起来像是十六进制格式,每个字符之间用00分隔,所以如果我运行以下语句:

SELECT CHAR(0x54)
SELECT CHAR(0x45)

这将返回:

T
E

有什么办法可以在一条语句中转换整个字符串?

谢谢!

1 个答案:

答案 0 :(得分:3)

00指向 2字节编码,它表示为NVARCHAR。试试这个

SELECT CAST(0x540045005300540049004E00470031003200330034 AS NVARCHAR(MAX))

或直接从十六进制字符串作为字符串:

SELECT CAST(CONVERT(VARBINARY(MAX),'540045005300540049004E00470031003200330034',2) AS NVARCHAR(MAX));

结果为 TESTING1234

更多关于字符串编码的背景

SQL-Server完全知道两种类型的字符串:

  • 1字节编码 VARCHAR / CHAR
  • 2字节编码 nVARCHAR / nCHAR

1个字节的字符串是扩展的ASCII ,相关的归类提供了一个代码页,用于映射非普通拉丁字符(作为人的 not utf-8有时会告诉)。

2个字节的字符串是UCS-2(几乎与utf-16相同)。

我已经纠正了上面的 unicode 一词,因为实际上它是不正确的。

SQL Server无法直接解释许多编码。

上方的字符串看起来看起来很适合NVARCHAR,但这在任何情况下都不能保证。

更多关于二进制编码的背景

SQL Server知道BINARYVARBINARY是真正的BLOB类型。在SELECT中,它们以十六进制字符串形式显示,在脚本中,您可以将十六进制字符串用作本机输入。但重要的是要知道,此 HEX字符串不是实际值!,只是计算机屏幕上人类可读的表示形式。

有一个真实的字符串,它看起来像十六进制字符串(但不是)。

0x123 != '0x123'

如果您有一个字符串,它是一个十六进制字符串,但是以“普通”字符串的形式出现(例如,在基于文本的容器(例如CSV文件或XML)中),则必须进行转换。

而且,与这个问题并没有真正的关系,只需提及一下:还有更多基于字符串的二进制表示符,例如base64。

一些例子

--start with a normal string 
DECLARE @str VARCHAR(100)='This is a test to explain conversions from string to hex to binary and back';
--see the HEX string (real binary!)
SELECT CAST(@str AS VARBINARY(MAX)) ThisIsTheHexStringOfTheString;

--I copy the binary behind the "=" _wihtout_ quotes
DECLARE @ThisIsTheBinary VARBINARY(MAX)=0x546869732069732061207465737420746F206578706C61696E20636F6E76657273696F6E732066726F6D20737472696E6720746F2068657820746F2062696E61727920616E64206261636B;
--This can be re-casted directly
SELECT CAST(@ThisIsTheBinary AS VARCHAR(MAX)) ThisIsReconvertedBinary;

--there is an undocumented function providing a HEX-string from a binary
DECLARE @aHEXstring VARCHAR(MAX)=sys.fn_varbintohexstr(CAST(@str AS VARBINARY(MAX)));
--This string looks exactly the same as above, but it is a string
SELECT @aHEXstring AS ThisIsStringWhichLooksLikeHEX;

--You can use dynamic SQL
EXEC('SELECT CAST(' + @aHEXstring + ' AS VARCHAR(MAX)) AS CastedViaDynamicSQL');
--or CONVERT's abilities (read the documentation!)
SELECT CAST(CONVERT(VARBINARY(MAX),@aHEXstring,1) AS VARCHAR(MAX)) AS ConvertedViaCONVERT