回答

收藏

在SQL Server中合并XML

技术问答 技术问答 297 人阅读 | 0 人回复 | 2023-09-13

假设我的数据库中有以下两段XML
1 m/ z% {1 G& M" m/ k" Z4 k
% B" S7 @4 i$ f9 D" [9 y! p    xml 1 a value5 y# i+ M/ a3 Q# F+ z. c
    xml 1 b value
. d  s# z" ~$ f    xml 1 c value) F' x. \% D% z: q; h' t

  b* V) z! u- O! ]# K) x' \    6 n6 g5 M9 A; u- Y4 Z0 ~
    xml 2 c value+ V) i( h+ B" b% J. U8 E# z
    xml 2 d value9 D. b$ e2 {# Y' D0 h; i2 g
    xml 1 e value
4 ~6 a1 l/ W6 q( e! W
/ V0 [. u5 d4 D# G此数据使用XML数据类型存储在两个单独的表中,此外,此XML列链接到描述所需xml格式的模式,例如
" t9 p; J+ ^* K* S2 E. A* h! S' _! q[PairData] [xml](CONTENT [foo].[Pairs]) NULL
% e; Q# q6 Q" u9 ]% B% L在存储过程/函数中,我想将这两个XML结构合并为以下内容:
4 [4 c; T1 Z, h6 P# @- G
: _, C6 o! c" o0 b0 G8 L; p2 Z' _) r( g1 ?    xml 1 a value! ]0 S& c" O! t% n" P' Q. F
    xml 1 b value  o$ V) O: f: Z
    xml 2 c value
1 d7 @$ M- K" C7 k    xml 2 d value
. h8 Q; t5 \6 M. N+ b; z. ?    xml 2 e value2 H! U3 A. Y: e- ~
$ ?1 v& h" k- R+ N0 F8 D6 U7 @
因此,从xml的第一部分开始,我们采取了以下措施:
! D( H* Y3 R# Ja, b7 @  ?+ F& h  Q! ^( N
从第二段xml中我们获得了以下内容:
2 T  w$ C6 b1 [c, d, e" D6 q' |. D, ]# {- C+ k0 G% P
注意,这两段XML有一个共同的项目,其关键是:% d( }6 g7 f4 ]: i
c, |" H4 ]. @8 N* `% q0 [% h
在这种情况下,应在合并的xml中使用xml 2中的值(丢弃xml 1中的值)。另一种情况是XML
: s% z- F5 v) j  D1或2可以为NULL,因此合并过程应处理该问题,并简单地返回另一个。或两个都可以为NULL,在这种情况下,将返回NULL。
3 h& F4 i# H0 S& l' a! F顺便说一句,在我们当前的实现中,我们从数据库返回了两个XML文档,并在代码中进行了合并。但是,我们希望在数据库中完成此合并,因为多个不相关的进程正在调用此proc。
- T5 o; l) O# ^& }2 {4 P8 m1 b               
) [' v, a0 b1 ~: f解决方案:+ P8 K  J, l2 c8 v7 D" h+ r
               
& o4 O2 W' K5 v& }$ ?. m& R1 \& c" R. I5 q4 V  i# v

" W8 A  S* ^8 \9 O                使用:9 S) K; A7 \; a2 m
declare @x1 xml ='
6 S: z. v) b. g8 \& b! j& K    xml 1 a value
0 H$ K( @7 y& i4 t% r. [+ v. ^4 l    xml 1 b value2 o5 F1 V/ W4 g* J) d# j
    xml 1 c value
' D0 }4 ~! f2 U: E( P'/ F8 ^" A$ \  `  Q, a
declare @x2 xml ='
8 B1 Q( n; `8 b4 n' m    xml 2 c value2 M3 c  o3 o4 L6 `1 t" \2 d
    xml 2 d value
( G! X2 w* C4 Z1 x5 [) J    xml 2 e value
/ K6 w# \( S- @* a2 ?( ]* w+ t'
! ^6 Z( X$ d/ E: y% Iselect */ i1 t" A% p! Z1 ?" u6 D
from) ?; V9 P  R9 V5 \5 D1 G# _& l
(1 a  V+ Q$ c+ y3 L. {
    select isnull(t2.a, t1.a) [@key], isnull(t2.b, t1.b) [text()]
7 u# H4 y8 W. r3 v    from
* A; c4 N0 ?9 U- l+ N7 v! v    (
5 B- w2 z! l& A" X! o1 k8 ^        select t.c.value('@key', 'nvarchar(max)') [a], t.c.value('.', 'nvarchar(max)') <strong>. `8 p. X- M5 ~& m$ Z5 N$ c
        from @x1.nodes('/*/item') t(c)# ^$ i8 H" u; s( b2 p0 K8 R
    )t1  S2 r7 ?5 O' ]# C2 e% U  q% E
    full join
. Z; V4 {4 S7 m- k    (8 j, f% f0 w4 z' Q: o/ x
        select t.c.value('@key', 'nvarchar(max)') [a], t.c.value('.', 'nvarchar(max)') <strong>
7 R; A1 G7 _  P        from @x2.nodes('/*/item') t(c)
# ?' J, `4 R( p! n    )t2 on t2.a = t1.a
+ f% K- T8 Y; O$ H8 i)t( A5 Q( A2 d( J, ^* d1 b8 J
for xml path('item'), root('pairs'), V: K5 o$ z7 e2 n2 d
输出:  g, Y3 g( ?' U7 f' x1 L1 [

: B5 j  F3 Q% O+ t& W; ^! X. l  xml 1 a value% A$ d3 v4 T0 x! n) n
  xml 1 b value8 g5 x6 v1 O+ f' t9 O
  xml 2 c value, b, C/ @* ~9 ^8 [2 A
  xml 2 d value' w1 ]0 @) }8 A5 @# X4 n7 j
  xml 2 e value" @( X& O9 F8 a' c
( M% i6 j4 l& G; x# X3 x1 [
更新:
/ `1 C# i" |; O$ t& R$ q# I! {declare @x1 xml ='
7 u* |9 }. M7 m    xml 1 a value
8 t5 {* }# L! w  }6 M: x    xml 1 b value0 l/ Z3 b* P: j6 R
    xml 1 c value9 G* i4 E- [4 ^6 p& l( |( s
'
% e2 H9 [3 s# i, V" v' t0 g2 gdeclare @x2 xml ='
; n( ]* _5 E$ `$ b, R& z) s    xml 2 c value' f2 H: h* b/ x. `& X
    xml 2 d value# u6 ~: D4 j2 ?- z. O
    xml 2 e value* [3 K+ R9 J9 \8 N
'
- V( S6 |& i8 Z2 V. v/ t, Adeclare @t1 table(id int, data xml)
% s) n6 }/ L6 K. Binsert @t1 values(1, @x1)
6 ^. M7 c6 i" n+ J0 Mdeclare @t2 table(id int, data xml)
4 ~, l* I! N# h& m9 z6 V2 q4 kinsert @t2 values(1, @x2)1 K1 i& v9 D& W" l( j
select isnull(t2.a, t1.a) [@key], isnull(t2.b, t1.b) [text()]) ^/ J4 C1 a8 @5 ~' a6 ?$ \6 R! Z
from
% u0 m4 h( R& m! P& b* P! o(, I5 x6 }1 A/ y) m
    select t.c.value('@key', 'nvarchar(max)') [a], t.c.value('.', 'nvarchar(max)') <strong>: ?0 c$ h& Q* N4 L$ Y
    from @t1 ta6 |& [6 ~$ d+ X
    cross apply ta.data.nodes('/*/item') t(c)3 M' k) q6 _+ d& k4 p+ l. O5 P1 e
)t1
. N0 A0 I) u: x$ rfull join
2 {+ z. @5 A4 W) y# |9 A1 k(8 P5 |, x0 @3 c1 l6 \
    select t.c.value('@key', 'nvarchar(max)') [a], t.c.value('.', 'nvarchar(max)') <strong>5 k! h' b9 P& \" v/ K: z
    from @t2 ta" A) M; Y# S& a, p! K+ C
    cross apply ta.data.nodes('/*/item') t(c)# {) j- z% B; o  p
)t2 on t2.a = t1.a& h" b& ?" j, [: i9 X
for xml path('item'), root('pairs')
分享到:
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则