SQL Server 2005中varbinary(max)列中的XML无效。

7

我在SQL Server 2005中有一个varbinary(max)列,其中包含许多XML。但是某些记录的XML被截断,因此它们是无效的。

这意味着如果我运行

SELECT CAST(myVarbinaryColumn as XML) ... 

it blows chunks.

(它很糟糕。)

如何过滤/跳过无效的xml?

当我使用varchar进行类似操作时,可以使用ISDATE(blah) = 1来判断日期是否有效。因此,一个等效的ISVALIDXML()函数会很好。

请不要评论“为什么列不是XML数据类型..”这已经发生在过去了,我没有时间机器。


嗯,有趣的是,最后几个字节总是相同的,所以我可以过滤掉那些不匹配的部分?幸运的是,在这种情况下,所有的xml都使用相同的模式,所以它们应该都有一个匹配的闭合根元素。 - hollystyles
2个回答

1

我认为你最好的选择是编写一个自定义CLR函数, 也许使用XmlDocument.Load。在CLR中,你可以捕获加载失败的错误,并返回适当的结果。

编辑: 下面的代码也可以工作,但不如UDF优雅。不幸的是,在UDF中我们不能使用TRY/CATCH。

create procedure dbo.usp_IsValidXML(@XMLCandidate varbinary(max), @Return bit output)
as
begin
    declare @x xml
    begin try
        set @x = cast(@XMLCandidate as xml)
        set @Return = 1
    end try
    begin catch
        set @Return = 0
    end catch
end
go

declare @test1 varbinary(max)
declare @test2 varbinary(max)
set @test1 = cast('<data>asdf</data>' as varbinary(max))
set @test2 = cast('<data>asdf</da' as varbinary(max))

declare @IsValid bit
exec dbo.usp_IsValidXML @test1, @IsValid output
select @IsValid
exec dbo.usp_IsValidXML @test2, @IsValid output
select @IsValid

drop procedure dbo.usp_IsValidXML

是的,并且创建一个基于该列的持久化计算列,以便每次执行“where valid_xml = 1”时不必调用它。 - GSerg

1

我希望我也有那个IsValidXML()函数.....不幸的是,我认为没有类似的东西.....

只是想:有什么可以检查以过滤无效的 XML 吗?

例如,你能过滤掉所有不以 .....</data> 结尾或类似的字符串吗?(因为你说你的无效 XML 通常是截断的 XML,所以我认为在这些情况下缺少闭合标签 - </data> 或其他标签)。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接