假设我的数据库中有以下两段XML
<!-- XML 1 --> <pairs> <item key="a">xml 1 a value</item> <item key="b">xml 1 b value</item> <item key="c">xml 1 c value</item> </pairs> <!-- XML 2 --> <pairs> <item key="c">xml 2 c value</item> <item key="d">xml 2 d value</item> <item key="e">xml 1 e value</item> </pairs>
此数据使用XML数据类型存储在两个单独的表中,此外,此XML列链接到描述所需xml格式的模式,例如
XML
[PairData] [xml](CONTENT [foo].[Pairs]) NULL
在存储过程/函数中,我想将这两个XML结构合并为以下内容:
<pairs> <item key="a">xml 1 a value</item> <item key="b">xml 1 b value</item> <item key="c">xml 2 c value</item> <item key="d">xml 2 d value</item> <item key="e">xml 2 e value</item> </pairs>
因此,从xml的第一部分开始,我们采取了以下措施:
a, b
从第二段xml中我们获得了以下内容:
c, d, e
注意,这两段XML有一个共同的项目,其关键是:
c
在这种情况下,应在合并的xml中使用xml 2中的值(丢弃xml 1中的值)。另一种情况是XML 1或2可以为NULL,因此合并过程应处理该问题,并简单地返回另一个。或两个都可以为NULL,在这种情况下,将返回NULL。
顺便说一句,在我们当前的实现中,我们从数据库返回了两个XML文档,并在代码中进行了合并。但是,我们希望在数据库中完成此合并,因为多个不相关的进程正在调用此proc。
使用:
declare @x1 xml ='<pairs> <item key="a">xml 1 a value</item> <item key="b">xml 1 b value</item> <item key="c">xml 1 c value</item> </pairs>' declare @x2 xml ='<pairs> <item key="c">xml 2 c value</item> <item key="d">xml 2 d value</item> <item key="e">xml 2 e value</item> </pairs>' select * from ( select isnull(t2.a, t1.a) [@key], isnull(t2.b, t1.b) [text()] from ( select t.c.value('@key', 'nvarchar(max)') [a], t.c.value('.', 'nvarchar(max)') [b] from @x1.nodes('/*/item') t(c) )t1 full join ( select t.c.value('@key', 'nvarchar(max)') [a], t.c.value('.', 'nvarchar(max)') [b] from @x2.nodes('/*/item') t(c) )t2 on t2.a = t1.a )t for xml path('item'), root('pairs')
输出:
更新:
declare @x1 xml ='<pairs> <item key="a">xml 1 a value</item> <item key="b">xml 1 b value</item> <item key="c">xml 1 c value</item> </pairs>' declare @x2 xml ='<pairs> <item key="c">xml 2 c value</item> <item key="d">xml 2 d value</item> <item key="e">xml 2 e value</item> </pairs>' declare @t1 table(id int, data xml) insert @t1 values(1, @x1) declare @t2 table(id int, data xml) insert @t2 values(1, @x2) select isnull(t2.a, t1.a) [@key], isnull(t2.b, t1.b) [text()] from ( select t.c.value('@key', 'nvarchar(max)') [a], t.c.value('.', 'nvarchar(max)') [b] from @t1 ta cross apply ta.data.nodes('/*/item') t(c) )t1 full join ( select t.c.value('@key', 'nvarchar(max)') [a], t.c.value('.', 'nvarchar(max)') [b] from @t2 ta cross apply ta.data.nodes('/*/item') t(c) )t2 on t2.a = t1.a for xml path('item'), root('pairs')