Если вы можете использовать SQL CLR, я предлагаю написать функцию, используя XNode.DeepEquals Method :
var xmlTree1 = new XElement("Root",
new XAttribute("Att1", 1),
new XAttribute("Att2", 2),
new XElement("Child1", 1),
new XElement("Child2", "some content")
);
var xmlTree2 = new XElement("Root",
new XAttribute("Att1", 1),
new XAttribute("Att2", 2),
new XElement("Child1", 1),
new XElement("Child2", "some content")
);
Console.WriteLine(XNode.DeepEquals(xmlTree1, xmlTree2));
Если вы не можете, вы можете написать свою собственную функцию (см. ПРИМЕР SQL FIDDLE ):
CREATE function [dbo].[udf_XML_Is_Equal]
(
@Data1 xml,
@Data2 xml
)
returns bit
as
begin
declare
@i bigint, @cnt1 bigint, @cnt2 bigint,
@Sub_Data1 xml, @Sub_Data2 xml,
@Name varchar(max), @Value1 nvarchar(max), @Value2 nvarchar(max)
if @Data1 is null or @Data2 is null
return 1
--=========================================================================================================
-- If more than one root - recurse for each element
--=========================================================================================================
select
@cnt1 = @Data1.query('count(/*)').value('.','int'),
@cnt2 = @Data1.query('count(/*)').value('.','int')
if @cnt1 <> @cnt2
return 0
if @cnt1 > 1
begin
select @i = 1
while @i <= @cnt1
begin
select
@Sub_Data1 = @Data1.query('/*[sql:variable("@i")]'),
@Sub_Data2 = @Data2.query('/*[sql:variable("@i")]')
if dbo.udf_XML_Is_Equal_New(@Sub_Data1, @Sub_Data2) = 0
return 0
select @i = @i + 1
end
return 1
end
--=========================================================================================================
-- Comparing root data
--=========================================================================================================
if @Data1.value('local-name(/*[1])','nvarchar(max)') <> @Data2.value('local-name(/*[1])','nvarchar(max)')
return 0
if @Data1.value('/*[1]', 'nvarchar(max)') <> @Data2.value('/*[1]', 'nvarchar(max)')
return 0
--=========================================================================================================
-- Comparing attributes
--=========================================================================================================
select
@cnt1 = @Data1.query('count(/*[1]/@*)').value('.','int'),
@cnt2 = @Data1.query('count(/*[1]/@*)').value('.','int')
if @cnt1 <> @cnt2
return 0
if exists (
select *
from
(
select
T.C.value('local-name(.)', 'nvarchar(max)') as Name,
T.C.value('.', 'nvarchar(max)') as Value
from @Data1.nodes('/*[1]/@*') as T(C)
) as D1
full outer join
(
select
T.C.value('local-name(.)', 'nvarchar(max)') as Name,
T.C.value('.', 'nvarchar(max)') as Value
from @Data2.nodes('/*[1]/@*') as T(C)
) as D2
on D1.Name = D2.Name
where
not
(
D1.Value is null and D2.Value is null or
D1.Value is not null and D2.Value is not null and D1.Value = D2.Value
)
)
return 0
--=========================================================================================================
-- Recursively running for each child
--=========================================================================================================
select
@cnt1 = @Data1.query('count(/*[1]/*)').value('.','int'),
@cnt2 = @Data2.query('count(/*[1]/*)').value('.','int')
if @cnt1 <> @cnt2
return 0
select @i = 1
while @i <= @cnt1
begin
select
@Sub_Data1 = @Data1.query('/*/*[sql:variable("@i")]'),
@Sub_Data2 = @Data2.query('/*/*[sql:variable("@i")]')
if dbo.udf_XML_Is_Equal(@Sub_Data1, @Sub_Data2) = 0
return 0
select @i = @i + 1
end
return 1
END