错误:非法的XML字符

时间:2011-07-13 16:32:04

标签: sql sql-server xml sql-server-2005 sql-server-2008

我有一个带有文本数据类型的列,但它是一个xml字段。当我尝试执行一个简单的语句,如

SELECT columnname,
       CONVERT(xml,coloumnname) 
  FROM employee

这在QA中运行良好,因为它的数据量很小。当我在生产中运行时,异常即将发生。有没有办法可以绕过所有具有非法xml字符的记录,以便我可以成功执行代码。使用sql sever 2005/2008。

有没有人有这方面的手册?

2 个答案:

答案 0 :(得分:4)

严肃地说,你应该清理你的数据。这里合法指定了一组合法的XML字符:http://www.w3.org/TR/xml/#charsets

在XML中使用任何非法字符都是坏消息。而不是试图“跳过”这些数据,你需要解决根本问题,这是一个糟糕的数据。

你能编写一个脚本来清理数据库中的数据吗?

我认为您的实时应用程序可以读取数据并对其进行预处理,在调用CONVERT之前查找错误的字符,但这不能解决根本问题而且效率不高。

答案 1 :(得分:1)

即时验证数据足够慢。

  1. 如果您确实不想使用错误数据,则应向表中添加列(例如“Is_Validated”)。

  2. 然后运行将检查数据的脚本,如果它无异常转换为xml,则将列更新为1,否则为0.

  3. 运行语句时,应限制转换为仅使用Is_Validated = 1的xml。

  4. 插入新行时,请检查是否为有效的XML(使用TRY / CATCH逻辑或CLR)并仅插入有效行。

  5. 当您保持逻辑稳定时,您可以开始验证您的错误数据。

  6. <强>更新

    由于来自#2的脚本应该只运行一次,它可以是简单的TSQL: 假设您的主键ID为int,而xml列由MySchema验证的表Employee中的Columnname

     Declare @id int=0,@xml XML(MySchema)
    WHILE EXISTS(SELECT * FROM Employee WHERE Id>@Id)
    BEGIN
         SELECT TOP 1 @Id=Id FROM Employee WHERE Id>@Id ORDER BY Id
    BEGIN TRY
      SET @xml=(SELECT columnname FROM Employee WHERE id=@Id)
          UPDATE Employee SET Is_Validated=1 WHERE Id=@Id
    END TRY
        BEGIN CATCH
            UPDATE Employee SET Is_Validated=0 WHERE Id=@Id
        END CATCH
        END