【问题标题】:Greek characters get corrupted when returned as part of XML element in SQL Server在 SQL Server 中作为 XML 元素的一部分返回时,希腊字符会损坏
【发布时间】:2018-04-05 09:09:06
【问题描述】:

我在 SQL Server 中编写了一个存储过程,它使用以下代码返回 XML:

DECLARE @error1 XML, @error2 XML

SET @error1 = 
(
    SELECT 1 AS '@Code', 
           CAST(Ν'My message in Greek' AS NVARCHAR(MAX)) COLLATE Greek_CI_AS AS '@Message'
    WHERE NOT EXISTS (SELECT 1 FROM #Employee)  
    FOR XML PATH ('Error')
)

SET @error2 = 
(
   ... Similar query here
)

IF (@error1 IS NOT NULL) OR (@error2 IS NOT NULL) 
BEGIN
      SELECT @error1, @error2
      FOR XML PATH('Errors'))
   RETURN
END

我在客户端使用以下代码来读取消息:

XElement xe = null;
using (SqlCommand cmdSelect = new SqlCommand("usp_MyProc", connection))
{
   cmdSelect.CommandType = CommandType.StoredProcedure;
   using (XmlReader xmlReader = cmdSelect.ExecuteXmlReader())
   {
      xe = XElement.Load(xmlReader);
   }
}

if (xe != null)
{
    lblResults.Text = xe.Descendants("Error")
                        .Where(x => (int)x.Attribute("Code") == 1)
                        .FirstOrDefault()
                        .Attribute("Message")
                        .Value;
}

不幸的是,lblResults.Text 被设置为 '��� ???????? ????' 之类的东西。关于问题的原因以及如何解决的任何想法?

编辑:

我设法找到了错误的来源。我的 proc 包含在我在 Visual Studio 中创建的“SQL Server 数据库项目”中。该问题是在项目发布到 SQL Server 时引起的。存储过程中的任何硬编码希腊字符在上传到服务器时都会损坏。

这是项目在 Visual Studio 中的样子:

下图为发布配置文件配置

【问题讨论】:

  • 愚蠢的问题 - 你忘了领先的N吗? N'My big fat greek message here'
  • Giorgos,您最后的编辑添加了N。这没有解决问题?
  • Όχι δεν χαλάνε。只有将它们加载为 ASCII 时,才会出现转换错误。当您加载数据时,数据丢失了(这就是发生的情况)。 ? 和实际的 Unicode 替换字符 之间的混合意味着一些数据使用 OLEDB 源、一些使用 .NET 或其他使用 而不是 ? 的源进行了破坏
  • @PanagiotisKanavos 存储在数据库中的数据没有问题。问题在于 proc 内的硬编码希腊字符。项目发布到服务器后,所有内容,甚至 cmets 都会损坏。我可以通过在服务器上手动部署 proc 来解决这个问题,但如果可能的话,我想避免这种情况,
  • Any hard-coded Greek characters inside the stored procedure are corrupted when uploaded to the server. 这意味着您的 code 是 ASCII。文件保存为 ASCII 而不是 UTF8 和/或字符串文字是 ASCII,例如 'Κάποιο όνομα' 是一个 ASCII 字符串文字,SQL Server 必须 使用服务器的排序规则将其转换为 Unicode,而 @ 987654338@ 是一个 Unicode 字符串文字。

标签: c# sql-server xml linq


【解决方案1】:

在您的文字前放置一个N 可能就足够了:

CAST(N'My message in Greek' AS NVARCHAR(MAX)) COLLATE Greek_CI_AS 

试试这个:

SELECT  'αλφάβητο' WithoutTheN
      ,N'αλφάβητο' WithN

根据COLLATION,第一个表达式将返回或多或少脏:使用我的默认值,我得到

a?f?ß?t?    αλφάβητο 

更新

OP 中的最后一次编辑确实添加了N

但是 - 如果不涉及其他任何事情 - 我看不出有任何其他原因,为什么这会出错。 XML 是——无论如何! - NVARCHARC# 在任何情况下都使用 unicode 字符串。两者之间没有任何地方正在发生变化。

可能是,SP usp_MyProcOUTPUT 被声明为 VARCHAR...

【讨论】:

  • 哈!我更快:-) +1
  • @ZoharPeled 是的,大约 10 秒...下次必须打字更快:-)
  • 无论如何,Giorgos 似乎只是在问题中忘记了这一点 - 它现在已编辑,所以可能是另一回事......
  • @ZoharPeled 是的,我自己也发现了这个……查看我的更新
猜你喜欢
  • 1970-01-01
  • 2018-02-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-07-10
  • 2022-07-06
相关资源
最近更新 更多