【发布时间】:2019-05-16 22:58:23
【问题描述】:
背景 - 我正在接收来自网站的响应数据,格式为 UTF-8 编码的 json 格式。 json 的 body 属性具有 base64binary 类型的值,我将其作为 nvarchar 类型存储在 ms sql server 上。
当我将该 base64binary 数据转换为 varchar 或 nvarchar 时,我看到有趣的字符(代替双引号)表明存在编码问题 - 这就是我问这个问题的原因。
请参阅下面的剖析代码和底部的可运行示例以及我的担忧。
在转换过程中注意有趣的字符。
例如。代表 IRB Holding Corp(——公司“)
以下查询修复了上述问题 - 我看到 quotes 应该出现,但是它在包含 '&' 的行上失败,这是 xml 中的一个特殊字符.
select convert(xml, '<?xml version="1.0" encoding="UTF-8"?>' + convert(varchar(max),cast('' as xml).value('xs:base64Binary(sql:column("body"))','varbinary(max)')))
以下查询使用replace 语句处理上述问题,我能够按预期完全查看所有行。但是这个解决方案只会处理'&' s。
要运行的示例代码:
declare @t table ( [body] nvarchar(max) )
insert into @t(body)
select 'REFMTEFTLCBUWCDigJMgTWF5IDcsIDIwMTkg4oCTIENvdmV5ICYgUGFyayBFbmVyZ3kgSG9sZGluZ3MgTExDICjigJxDb3ZleSBQYXJr4oCdIA=='
select convert(varchar(max),cast('' as xml).value('xs:base64Binary(sql:column("body"))','varbinary(max)'))
, convert(xml, '<?xml version="1.0" encoding="UTF-8"?>'+ replace(convert(varchar(max),convert(varchar(max),cast('' as xml).value('xs:base64Binary(sql:column("body"))','varbinary(max)'))),'&','&'))
from @t
问题 - 我是否必须为其他 xml 特殊字符添加更多替换语句 - < , > ?
【问题讨论】:
-
@GSerg,如果性能不那么重要,这是一个很好的解决方法。谢谢链接!我用给定的字符串尝试了函数并返回了
DALLAS, TX – May 7, 2019 – Covey & Park Energy Holdings LLC (“Covey Park”,这看起来很有说服力。 -
@Shnugo 没有一种解决方法(它们都是)将是高效的。最快的解决方法应该将
varbinary(max)传递给CLR 函数并在其上调用Utf8.GetString。原则上最快的应该是 SQL Server 2019 中的cast(cast(varbinary as varchar(max)) collate LATIN1_GENERAL_100_CI_AS_SC_UTF8 as nvarchar(max))。 -
@GSerg True... 但最快的是,知道所有这些,因此完全避免在数据库存储中使用 UTF-8。我刚刚在我的答案中添加了几行来反映这一点。
-
GSerg 和 Snugo,感谢您的解释。也学到了一些新东西。添加 cdata 块正确转换了我的表中的所有记录 - 现在 xml 的陷阱不在我的路径中,当我继续提取更多数据时会看到它是如何进行的,是的,我需要阅读 cdata 的工作原理。跨度>
标签: json sql-server xml encoding utf-8