【发布时间】:2022-01-06 09:41:34
【问题描述】:
我有一个 varbinary(max) 列,其中包含已压缩的 UTF-8 编码文本。我想解压缩这些数据,并使用 SQL Server 的 UTF-8 功能在 T-SQL 中将其作为 varchar(max) 使用。
我正在寻找一种在从 varbinary(max) 转换为 varchar(max) 时指定编码的方法。我设法做到这一点的唯一方法是创建一个带有 UTF-8 排序规则列的表变量,并将 varbinary 数据插入其中。
DECLARE @rv TABLE(
Res varchar(max) COLLATE Latin1_General_100_CI_AS_SC_UTF8
)
INSERT INTO @rv
SELECT SUBSTRING(Decompressed, 4, DATALENGTH(Decompressed) - 3) WithoutBOM
FROM
(SELECT DECOMPRESS(RawResource) AS Decompressed FROM Resource) t
我想知道是否有一种更优雅、更有效的方法,不涉及插入到表变量中。
更新:
将其归结为一个不涉及字节顺序标记或压缩的简单示例:
我有字符串“Hello ????” UTF-8 编码,没有存储在变量 @utf8Binary 中的 BOM
DECLARE @utf8Binary varbinary(max) = 0x48656C6C6F20F09F988A
现在我尝试将其分配给各种基于字符的变量并打印结果:
DECLARE @brokenVarChar varchar(max) = CONVERT(varchar(max), @utf8Binary)
print '@brokenVarChar = ' + @brokenVarChar
DECLARE @brokenNVarChar nvarchar(max) = CONVERT(varchar(max), @utf8Binary)
print '@brokenNVarChar = ' + @brokenNVarChar
DECLARE @rv TABLE(
Res varchar(max) COLLATE Latin1_General_100_CI_AS_SC_UTF8
)
INSERT INTO @rv
select @utf8Binary
DECLARE @working nvarchar(max)
Select TOP 1 @working = Res from @rv
print '@working = ' + @working
这样的结果是:
@brokenVarChar = Hello 😊
@brokenNVarChar = Hello 😊
@working = Hello ????
所以我能够使用这种间接方法正确解码二进制结果,但我想知道是否有更直接(并且可能更有效)的方法。
【问题讨论】:
-
至少一个示例(压缩)值会真正帮助我们在这里为您提供帮助。
-
@Larnu,感谢您的建议。我添加了一个示例脚本。
-
非常好的问题。 According to the documentation,
CAST(@utf8Binary AS varchar(max)) COLLATE Latin1_General_100_CI_AS_SC_UTF8应该工作,但它没有。 -
老实说,在我的沙盒环境中,我得到了一些非常奇怪的结果......看看这个animated GIF,其中一个函数的行为是一个数据库发生变化,因为我创建了另一个数据库;跨度>
-
如果有人对 ADS 行为感兴趣,请Github Issue。
标签: sql-server tsql