我在MS SQL 2005中有一个XML存储过程,我使用SqlCommand.ExecuteXmlReader获取XmlReader,然后解析数据并形成XML文档。问题是SQL中的数据包含一些在UTF-8 XML文档中非法的二进制字符,因此抛出异常。
还有其他人处理过这个问题吗?我考虑过将输入数据过滤到数据库中,但是我必须将过滤放到任何地方,并且需要检查每个字符。
还有其他建议吗?
修改 数据通常存储在各种长度的varchar列中。实际上,数据来自Web表单上的用户(ASP .NET应用程序)。因此,有时它们会从MS Word或其他东西进行复制粘贴,并将这些奇怪的二进制字符放入其中。
答案 0 :(得分:1)
我已经看过数据库中nvarchar列的DotNet SqlClient“scramble”数据,我们的理论与“代理代码点”有关,请参阅:
http://www.siao2.com/2005/07/27/444101.aspx
http://publib.boulder.ibm.com/infocenter/iseries/v5r3/index.jsp?topic=rzaaxsurrogate.htm
SqlClient似乎“解释”了我们的Xml不再格式化的一些字节,转换为nvarchar(max)似乎阻止了这一点(尽管这确实会对性能产生影响):
SELECT CONVERT(NVARCHAR(MAX), MyValue) FROM ...
请注意,您需要使用NVARCHAR(MAX),NVARCHAR(N)无效。
我们还发现OleDB提供程序也能正常工作(尽管它比SqlClient慢)。
答案 1 :(得分:0)
坏数据是如何进入数据库的?您使用的是XML列吗?
您可以将过滤(实际上称为“验证”)放入用于将数据输入数据库的存储过程中,或者您可以添加触发器来检查数据,无论数据来自何处。
一般情况下,不要让错误的数据进入数据库!
答案 2 :(得分:0)
这是编码问题吗?或者xml是否格式错误?如果畸形,我情不自禁。但是对于编码......很遗憾ExecuteXmlReader
不允许您指定编码,但您可以将数据视为BLOB,并使用您自己的编码和XmlReader
单独处理它? / p>
如果数据很大,您可能希望将ExecuteReader
与CommandBehavior.SequentialAccess
一起使用并将其写入临时文件(Path.GetTempFileName()
) - 然后将该文件作为{{{ 1}}与Stream
。
答案 3 :(得分:0)
我已经抽象了应用程序中各处的SqlParameter对象的制作,所以我将在那时擦除输入。我的抽象方法创建并返回一个SqlParameter对象,以便在存储过程调用中使用。如果它是调用者想要的varchar,我将循环遍历他们想要生成的字符串的每个字符到SqlParameter对象中,并过滤掉那些非法的二进制XML字符。这将首先消除不良数据进入数据库。
答案 4 :(得分:0)
您的存储过程如何生成XML?如果在SQL Server中使用任何FOR XML选项,则文本字段中的二进制字符将被正确转义:
CREATE TABLE test (
id int identity(1,1) not null primary key,
data nvarchar(50))
INSERT INTO test (data) values (char(0))
SELECT * FROM test FOR XML RAW
产生
<row ID="1" data="�" />