2010-09-22 1 views
7

Quindi ho ottenuto una colonna varbinary(max) in SQL Server 2005 ed è piena di XML. Alcuni record hanno troncato XML in modo che non siano validi.XML non valido in una colonna varbinary (max) in SQL Server 2005

Questo significa che se corro un

SELECT CAST(myVarbinaryColumn as XML) ... 

soffia pezzi.

Come posso filtrare/saltare xml non valido?

Quando ho fatto simile con un varchar che presumibilmente ha date che potrei usare ISDATE(blah) = 1. Quindi un equivalente ISVALIDXML() sarebbe bello.

Si prega di non commentare "Perché non è il tipo di dati XML della colonna comunque .." Questo è successo in passato e non ho una macchina del tempo.

+0

Hmm interessante, i byte finali saranno sempre gli stessi in modo da poter filtrare quelli che non corrispondono? Fortunatamente in questo scenario gli xml utilizzano tutti lo stesso schema, quindi dovrebbero avere tutti un elemento radice di chiusura corrispondente –

risposta

1

Penso che la soluzione migliore sarebbe scrivere un numero personalizzato CLR function, magari usando XmlDocument.Load. Nel CLR è possibile intercettare l'errore su un carico non riuscito e restituire un risultato appropriato.

EDIT: Il codice seguente funzionerà anche se non è elegante come un UDF. Sfortunatamente, non possiamo usare TRY/CATCH in un UDF.

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

Sì e creare una colonna calcolata persistente basata su di esso, quindi non viene chiamata ogni volta che si va 'where valid_xml = 1'. – GSerg

+0

Sarà deterministico? –

1

Vorrei avere che IsValidXML() funzione, troppo ..... purtroppo, non credo ci sia niente di simile .....

Solo un pensiero: c'è qualcosa che si potrebbe verificare la presenza di filtrare l'XML non valido ??

E.g. potresti filtrare tutte quelle stringhe che non finiscono in .....</data> o qualcosa del genere ?? (visto che dici che il tuo XML non valido è tipicamente XML troncato, quindi penso che il tag di chiusura - </data> o qualsiasi altra cosa - manchi in questi casi).