尝试将 XML 内容存储到 SQL Server 2005 中失败(编码问题)
Posted
技术标签:
【中文标题】尝试将 XML 内容存储到 SQL Server 2005 中失败(编码问题)【英文标题】:Trying to store XML content into SQL Server 2005 fails (encoding problem) 【发布时间】:2010-09-27 22:49:35 【问题描述】:伙计们,
我有一个以 ISO-8859-1 编码返回数据的网络服务 - 因为它不是我的,所以我无法更改它:-(
出于审计目的,我想将这些调用生成的 XML 存储到一个 SQL Server 2005 表中,其中我有一个类型为“XML NULL”的字段。
在我的 C# 代码中,我尝试使用参数化查询将此 XML 内容存储到 XML 字段中,类似于
SqlCommand _cmd = new SqlCommand("INSERT INTO dbo.AuditTable(XmlField) VALUES(@XmlContents)", _connection);
_cmd.Parameters.Add("@XmlContents", SqlDbType.Xml);
_cmd.Parameters["@XmlContents"].Value = (my XML response);
_cmd.ExecuteNonQuery();
问题是 - 当我运行这段代码时,我得到一个错误:
消息 9402,第 16 级,状态 1,第 1 行 XML解析:第1行,字符xy,无法切换编码
??我试图弄清楚我可以在哪里以及如何“切换”编码 - 到目前为止还没有运气。这到底是什么意思?我无法在 SQL Server 2005 中使用 ISO-8859-1 编码存储 XML?或者是否有一个技巧来 a) 告诉 SQL Server 2005 只接受这种编码,或者 b) 在存储到 SQL Server 之前自动将 Web 服务响应转换为 UTF 编码?
感谢任何提示、指点、提示! 马克
【问题讨论】:
仅供读者参考 - 几乎重复:***.com/questions/1564718/… 和 ***.com/questions/1564718/… 【参考方案1】:You need to convert to utf-16
即使我使用 SQL Server 中的 XML,我也不是专家,但我们去年遇到了同样的问题,与发送的 xml 相比,SQL 中声明的字符串数据类型不匹配。
【讨论】:
是的,它有点混乱和复杂,但它可以完成工作 - 感谢您的提示和链接! 这是不正确的 - 不需要转换为 UTF-16。请参考***.com/a/8998183/751158。 @gbn - 这个答案有一个死链接。【参考方案2】:我在谷歌上找到了这个。 http://social.msdn.microsoft.com/forums/en-US/sqlxml/thread/d40ef582-4ffe-4f4b-b6b8-03c6c0ba1a32/
我觉得你可以换行
_cmd.Parameters.Add("@XmlContents", SqlDbType.Xml);
与
_cmd.Parameters.Add("@XmlContents", System.Data.SqlTypes.SqlXml);
【讨论】:
嗨,Nathan,似乎不起作用 - 我收到编译时错误:错误 2 'System.Data.SqlTypes.SqlXml' is a 'type',在给定的上下文中无效想法??【参考方案3】:您能否将 xml 重写为 unicode(可能是 MemoryStream
)并发送?注意:如果您只是存储数据,您可以使用varbinary(max)
(实际上会更快)。这没有编码困难,并且还允许您审核收到的任何损坏的 xml。
如果您在数据库服务器中以 xml 格式查询数据,那么xml
显然是要走的路。
【讨论】:
感谢您的提示 - 但由于我想使用 XQuery 查询和报告数据,我确实需要将其作为 XML 保存在 SQL Server 2005 中。 然后也许看看简单地重写 xml 以在将其发送到服务器之前更改编码。【参考方案4】:我发布了一些信息:
http://mrboratech.blogspot.com/2009/02/how-to-store-xmldocument-mssql-2005-as.html
【讨论】:
【参考方案5】:编辑 我错过了问题的 ISO-8859-1 部分 - 下面的解决方案适用于 UTF8,但显然不能解决 Marc 的问题,因为他无法更改编码。
这是我使用的解决方案:
Inserting XML into a SQL Database上面的代码稍作修改(我已经使用 SQL 2005 使用 UTF8 文件对其进行了测试):
using System.IO;
using System.Text;
using System.Data;
using System.Data.SqlClient;
using System.Data.SqlTypes;
...
using (SqlConnection connection = new SqlConnection("conn string"))
connection.Open();
string sql = "INSERT INTO mytable (xmlColumn) VALUES (@xmlData)";
using (SqlCommand command = new SqlCommand(sql, connection))
// Swap round if the source file is unicode
string xml = File.ReadAllText(@"C:\myxml.xml");
//string xml = File.ReadAllText(@"C:\myxml.xml", Encoding.Unicode);
using (MemoryStream stream = new MemoryStream())
using (StreamWriter writer = new StreamWriter(stream, Encoding.Unicode))
writer.Write(xml);
writer.Flush();
stream.Position = 0;
SqlParameter parameter = new SqlParameter("@xmlData", SqlDbType.Text);
parameter.Value = new SqlXml(stream);
command.Parameters.Add(parameter);
command.ExecuteNonQuery();
【讨论】:
您是否在输入文件具有 ISO-8859-1 编码的情况下尝试过这个?此外,您缺少“使用”语句,所以 -1。 John,我相信您知道 MemoryStream.Dispose 什么都不做,所以那里没有任何好处,刷新 writer(即 writer.Dispose)会使 SqlCommand 留下一个已处置的 Writer。如果我在 Writer 的 using() 中执行了执行,那么 Writer 将不会被刷新并且是空的,这就是我为什么要像上面那样做的原因。该代码需要一个 UTF16 文件,因此它不适用于 IS0-8859(据我所知是 UTF8)。 错过了问题的 ISO-8859-1 部分,我的错 MemoryStream.Dispose 今天可能什么都不做。这是你永远不应该依赖的实现细节。当然,在 ExecuteNonQuery 完成之前不要结束使用。并且您需要将流位置设置回 0。 好吧,我接受了建议并更新了它。之前的代码正在运行(奇怪的是现在运行得更快了)。【参考方案6】:即使我在将 xml 内容插入数据库时也遇到了类似的问题。 对于 ex ,输入是这样的:
Insert Into TestData(Xml) Values ('<?xml version="1.0" encoding="UTF-8"?><Test/>')
这种语句过去常常失败,我得到“无法切换..”错误。后来我只是像这样在 xml 字符串中添加了 N 前缀:
Insert Into TestData(Xml) Values (N'<?xml version="1.0" encoding="UTF-8"?><Test/>')
之后它开始工作了!!!
【讨论】:
是的,如果你有一个文本 XML 字符串,那就可以了。以上是关于尝试将 XML 内容存储到 SQL Server 2005 中失败(编码问题)的主要内容,如果未能解决你的问题,请参考以下文章
将 xml 作为参数传递给 SQL Server 中的存储过程
如何设置“以属性的形式将xml数据插入到SQL Server2008数据库的表中”的存储过程
将 XML 文档从 SQL SERVER 插入到 Oracle
如何使用 Spark 从 XML 复制到 SQL Server
将 xml 字符串参数传递给 SQL Server 存储过程
如何将数据从 Magnolia CMS Apache Jackrabbit 内容存储库迁移到普通 SQL SERVER 数据库