SQL Server 和 UTF-8 XML [重复]

SQL Server and UTF-8 XML [duplicate]

提问人:AcclaroDev 提问时间:11/15/2023 最后编辑:AcclaroDev 更新时间:11/15/2023 访问量:53

问:

我四处搜索并注意到 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.

为什么一个人会失去记忆,而另一些人会抛出错误?

SQL-SERVER XML 统一码

评论

0赞 siggemannen 11/15/2023
你是说:?您可以阅读允许的内容:stackoverflow.com/questions/65534945/...<Name€>test</Name€>
1赞 Thom A 11/15/2023
您的数据库采用什么排序规则?我假设它不是 UTF-8 排序规则,就好像你是一样,问题不会发生。对于 ASCII 代码页,解析为 ;无法表示该字符。😎??
1赞 Panagiotis Kanavos 11/15/2023
您使用的是 ASCII,而不是 Unicode 字符串。您的查询在所有情况下都会失败,并且会破坏文本。通过添加前缀来改用 Unicode 字符串,所有 SQL Server 文档和示例的显示方式。这与 UTF8 无关,而是关于 ASCII 与 UnicodeN
0赞 Panagiotis Kanavos 11/15/2023
也使用 Unicode 类型而不是 ASCII 类型。如果您收到有关切换编码的错误,请删除 .SQL Server 始终支持 Unicode,而不必求助于编码。Unicode 字符串和类型使用 UTF16nvarcharvarcharencoding="utf-8"

答:

-1赞 Thom A 11/15/2023 #1

这种行为是完全意料之中的。将 Something like 放在文字字符串的开头不会改变所述文字字符串的排序规则,并且您拥有的文字字符串varchar我不知道你用什么排序规则,但如果你在UTF-8排序数据库中,你就不会有问题。但是,您不是意味着,当然,无法表示像这样的字符,因为它的缺陷远远超出了 ASCII 字符范围。<?xml version="1.0" encoding="utf-8"?>😎

如果不能使用 UTF-8 数据库,则需要将文本字符串和变量定义为 .然后,当您设置变量的值时,您需要将该值转换为 UTF-8 排序规则,并且:nvarchar@XMLCOLLATECONVERTvarchar

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;

评论

0赞 GSerg 11/15/2023
does not change the collation of said literal string- 这是正确的,但它可能仍然会影响将该文字字符串解析为 XML
1赞 Panagiotis Kanavos 11/15/2023
@GSerg在问题的示例中,它会抛出一个错误,抱怨切换编码
0赞 Thom A 11/15/2023
为了验证 Panagiotis 的评论,@GSerg:db<>fiddle
-1赞 Panagiotis Kanavos 11/15/2023 #2

问题中的所有查询都失败。所有这些都会破坏文本,因为它们使用以 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 编码。如果您尝试使用,则会收到一个错误,抱怨尝试切换编码。encodingutf-8

不过,这将起作用:

DECLARE @DT nVARCHAR(MAX) = N'<?xml version="1.0" ?>
<Names>
    <Name>😎</Name>
    <Name>€</Name>
    <Name>ä</Name>
    <Name>Μπανάνες</Name>
</Names>'