2010-09-22 89 views
7

因此,我在SQL Server 2005中獲得了varbinary(max)列,它充滿了XML。某處有幾條記錄截斷了XML,因此它們無效。SQL Server 2005中varbinary(max)列中的XML無效

這意味着,如果我跑

SELECT CAST(myVarbinaryColumn as XML) ... 

它吹塊。

如何過濾/跳過無效的XML?

當我已經完成類似與假定有日期的varchar我可以使用ISDATE(blah) = 1。所以相當於ISVALIDXML()會很好。

請不要評論「爲什麼不是列XML數據類型......」這發生在過去,我沒有時間機器。

+0

嗯有趣的是,最後的字節總是相同的,所以我可以過濾掉那些不匹配的東西?幸運的是,在這種情況下,xml都使用相同的模式,因此它們都應該有一個匹配的結束根元素 – 2010-09-22 16:33:20

回答

1

我認爲你最好的選擇是編寫自定義CLR function,或許使用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 
+0

是的,並基於它創建一個持久性計算列,所以每當你去'where valid_xml = 1'時都不會調用它。 – GSerg 2010-09-22 16:49:18

+0

它是確定性的嗎? – 2010-09-22 17:06:33

1

我希望我有這樣的IsValidXML()功能,太.....不幸的是,我不認爲有這樣的事情.....

只是一個想法:有什麼你可以檢查到過濾出無效的XML?

E.g.你能過濾掉所有那些不以.....</data>或類似的東西結束嗎? (看到你說你無效的XML通常是截斷的XML,所以我會認爲結束標記 - </data>或其他 - 在這些情況下會丟失)。

相關問題