提问人:AcclaroDev 提问时间:11/15/2023 最后编辑:AcclaroDev 更新时间:11/15/2023 访问量:53
SQL Server 和 UTF-8 XML [重复]
SQL Server and UTF-8 XML [duplicate]
问:
我四处搜索并注意到 SQL Server(我使用的是 2017)和 UTF-8 的一些问题。
从其他线程中,我看到如果您直接在XML中使用特殊字符(例如表情符号),则会丢失一些数据。
DECLARE @DT VARCHAR(MAX) = '<?xml version="1.0" encoding="utf-8"?>
<Name>😎</Name>
'
DECLARE @XML XML
SET @XML = @DT
SELECT @XML
-- Result: <Name>??</Name>
这很好。
但是当我使用或SQL抛出错误时:<Name>ä</Name>
<Name>€</Name>
Msg 9420, Level 16, State 1, Line 6
XML analysis: Line 2, character 7, invalid XML character.
为什么一个人会失去记忆,而另一些人会抛出错误?
答:
这种行为是完全意料之中的。将 Something like 放在文字字符串的开头不会改变所述文字字符串的排序规则,并且您拥有的文字字符串是 varchar
。我不知道你用什么排序规则,但如果你在UTF-8排序数据库中,你就不会有问题。但是,您不是意味着,当然,无法表示像这样的字符,因为它的缺陷远远超出了 ASCII 字符范围。<?xml version="1.0" encoding="utf-8"?>
😎
如果不能使用 UTF-8 数据库,则需要将文本字符串和变量定义为 .然后,当您设置变量的值时,您需要将该值转换为 UTF-8 排序规则,并且:nvarchar
@XML
COLLATE
CONVERT
varchar
DECLARE @DT nvarchar(MAX) = N'<Name>😎</Name>';
DECLARE @XML xml;
SET @XML = CONVERT(varchar(MAX),'<?xml version="1.0" encoding="utf-8"?>' + @DT COLLATE Latin1_General_100_CI_AI_SC_UTF8);
SELECT @XML;
评论
does not change the collation of said literal string
- 这是正确的,但它可能仍然会影响将该文字字符串解析为 XML。
问题中的所有查询都失败。所有这些都会破坏文本,因为它们使用以 ASCII 类型保存的 ASCII 字符串文字。SQL Server 始终通过 Unicode 类型(如 Unicode 文本)支持 Unicode。没有理由玩编码。nvarchar
此查询工作正常,不会破坏文本
DECLARE @DT nVARCHAR(MAX) = N'<Names>
<Name>😎</Name>
<Name>€</Name>
<Name>ä</Name>
<Name>Μπανάνες</Name>
</Names>'
DECLARE @XML XML
SET @XML = @DT
SELECT @XML
输出为:
<Names>
<Name>😎</Name>
<Name>€</Name>
<Name>ä</Name>
<Name>Μπανάνες</Name>
</Names>
你甚至不必使用 ,你可以将Unicode文字直接分配给列或变量:nvarchar(max)
XML
DECLARE @XML xml = N'<?xml version="1.0" ?>
<Names>
<Name>😎</Name>
<Name>€</Name>
<Name>ä</Name>
<Name>Μπανάνες</Name>
</Names>'
SELECT @XML
Unicode 类型和文本使用完整的 UTF-16 范围或缩小的 UCS-2 范围,具体取决于是否使用增补字符排序规则。
如果需要 prolog,请删除该属性。文本已使用 Unicode 编码。如果您尝试使用,则会收到一个错误,抱怨尝试切换编码。encoding
utf-8
不过,这将起作用:
DECLARE @DT nVARCHAR(MAX) = N'<?xml version="1.0" ?>
<Names>
<Name>😎</Name>
<Name>€</Name>
<Name>ä</Name>
<Name>Μπανάνες</Name>
</Names>'
评论
<Name€>test</Name€>
😎
??
N
nvarchar
varchar
encoding="utf-8"