我正在寻找一种方法来更新(.modify('insert into..') 具体而言)表中的 XML 列,其中包含来自由外键链接的另一个表的 xml 片段。
例如,我的表结构如下所示(简化):
- 每个表中的第 1 到第 5 字段可以忽略;他们的唯一目的是解释字段 Xx。
- 每个表中的字段 Xx 被定义为 XML,并预先填充了一个 XML 片段,该片段包含来自表中的字段的标记,表名。XML 片段在此列表之后描述。
- 表 B 和表 C 有一个外键 FK_A,将它们链接到表 A。表 A - B 和表 A - C 是一对多的(A 中的一条记录可以有 B 和 C 中的多条记录)。
现在,在我需要实现之前的 Xx 字段样本值:
<!-- Table A record 1 -->
<TableA PK_A="1">
<A1>Avalue</A1>
<A2>Avalue</A2>
<A3>Avalue</A3>
<A4>Avalue</A4>
<A5>Avalue</A5>
</TableA>
<!-- Table B record 1 -->
<TableB PK_B="1" FK_A="1">
<B1>Bvalue1</B1>
<B2>Bvalue1</B2>
<B3>Bvalue1</B3>
<B4>Bvalue1</B4>
<B5>Bvalue1</B5>
</TableB>
<!-- Table B record 2 -->
<TableB PK_B="2" FK_A="1">
<B1>Bvalue2</B1>
<B2>Bvalue2</B2>
<B3>Bvalue2</B3>
<B4>Bvalue2</B4>
<B5>Bvalue2</B5>
</TableB>
<!-- Table C record 1 -->
<TableC PK_C="1" FK_A="1">
<C1>Cvalue1</C1>
<C2>Cvalue1</C2>
<C3>Cvalue1</C3>
<C4>Cvalue1</C4>
<C5>Cvalue1</C5>
</TableC>
<!-- Table C record 2 -->
<TableC PK_C="2" FK_A="1">
<C1>Cvalue2</C1>
<C2>Cvalue2</C2>
<C3>Cvalue2</C3>
<C4>Cvalue2</C4>
<C5>Cvalue2</C5>
</TableC>
这里的问题是,如何通过将所有 XB 和 XC 作为第一个(或最后一个)插入相应的 XA 来更新表 A?我更喜欢单个操作来更新整个表。
操作后,XA 应如下所示:
<!-- Table A record 1 -->
<TableA PK_A="1">
<!-- Table B record 1 -->
<TableB PK_B="1" FK_A="1">
<B1>Bvalue1</B1>
<B2>Bvalue1</B2>
<B3>Bvalue1</B3>
<B4>Bvalue1</B4>
<B5>Bvalue1</B5>
</TableB>
<!-- Table B record 2 -->
<TableB PK_B="2" FK_A="1">
<B1>Bvalue2</B1>
<B2>Bvalue2</B2>
<B3>Bvalue2</B3>
<B4>Bvalue2</B4>
<B5>Bvalue2</B5>
</TableB>
<!-- Table C record 1 -->
<TableC PK_C="1" FK_A="1">
<C1>Cvalue1</C1>
<C2>Cvalue1</C2>
<C3>Cvalue1</C3>
<C4>Cvalue1</C4>
<C5>Cvalue1</C5>
</TableC>
<!-- Table C record 2 -->
<TableC PK_C="2" FK_A="1">
<C1>Cvalue2</C1>
<C2>Cvalue2</C2>
<C3>Cvalue2</C3>
<C4>Cvalue2</C4>
<C5>Cvalue2</C5>
</TableC>
<A1>Avalue</A1>
<A2>Avalue</A2>
<A3>Avalue</A3>
<A4>Avalue</A4>
<A5>Avalue</A5>
</TableA>
到目前为止我尝试了什么?
到目前为止,我最好的领导是分而治之的方法(一个两部分的解决方案,这是行不通的)。
WITH CTEB (PK_A, XA, XB)
AS (SELECT A.PK_A,
a.XA,
b.XB
FROM TableA AS a
INNER JOIN
TableB AS b
ON b.FK_A = a.PK_A)
UPDATE CTEB
SET XA.modify('insert sql:column("XB") as last into (/TableA)[1]');
WITH CTEC (PK_A, XA, XC)
AS (SELECT A.PK_A,
a.XA,
c.XC
FROM TableA AS a
INNER JOIN
TableC AS c
ON c.FK_A = a.PK_A)
UPDATE CTEC
SET XA.modify('insert sql:column("XC") as last into (/TableA)[1]');
编辑:
很抱歉没有提供任何文本值来复制粘贴。开始了。
DECLARE @A TABLE (PK_A INT, XA XML);
DECLARE @B TABLE (PK_B INT, XB XML, FK_A INT);
DECLARE @C TABLE (PK_C INT, XC XML, FK_A INT);
INSERT INTO @A
VALUES (1, '<TableA PK_A="1"><A1>Avalue</A1><A2>Avalue</A2><A3>Avalue</A3><A4>Avalue</A4><A5>Avalue</A5></TableA>')
INSERT INTO @A
VALUES (2, '<TableA PK_A="2"><A1>Avalue</A1><A2>Avalue</A2><A3>Avalue</A3><A4>Avalue</A4><A5>Avalue</A5></TableA>')
INSERT INTO @B
VALUES (1,'<TableB PK_B="1" FK_A="1"><B1>Bvalue1</B1><B2>Bvalue1</B2><B3>Bvalue1</B3><B4>Bvalue1</B4><B5>Bvalue1</B5></TableB>', 1)
INSERT INTO @B
VALUES (2, '<TableB PK_B="2" FK_A="1"><B1>Bvalue2</B1><B2>Bvalue2</B2><B3>Bvalue2</B3><B4>Bvalue2</B4><B5>Bvalue2</B5></TableB>', 1)
INSERT INTO @B
VALUES (3, '<TableB PK_B="3" FK_A="2"><B1>Bvalue3</B1><B2>Bvalue3</B2><B3>Bvalue3</B3><B4>Bvalue3</B4><B5>Bvalue3</B5></TableB>', 2)
INSERT INTO @B
VALUES (4, '<TableB PK_B="4" FK_A="2"><B1>Bvalue4</B1><B2>Bvalue4</B2><B3>Bvalue4</B3><B4>Bvalue4</B4><B5>Bvalue4</B5></TableB>', 2)
INSERT INTO @C
VALUES (1, '<TableC PK_C="1" FK_A="1"><C1>Cvalue1</C1><C2>Cvalue1</C2><C3>Cvalue1</C3><C4>Cvalue1</C4><C5>Cvalue1</C5></TableC>', 1)
INSERT INTO @C
VALUES (2, '<TableC PK_C="2" FK_A="1"><C1>Cvalue2</C1><C2>Cvalue2</C2><C3>Cvalue2</C3><C4>Cvalue2</C4><C5>Cvalue2</C5></TableC>', 1)
INSERT INTO @C
VALUES (3, '<TableC PK_C="3" FK_A="2"><C1>Cvalue3</C1><C2>Cvalue3</C2><C3>Cvalue3</C3><C4>Cvalue3</C4><C5>Cvalue3</C5></TableC>', 2)
INSERT INTO @C
VALUES (4, '<TableC PK_C="4" FK_A="2"><C1>Cvalue4</C1><C2>Cvalue4</C2><C3>Cvalue4</C3><C4>Cvalue4</C4><C5>Cvalue4</C5></TableC>', 2);
WITH CTEB (PK_A, XA, XB)
AS (SELECT A.PK_A,
a.XA,
b.XB
FROM @A AS a, @B as b
WHERE b.FK_A = a.PK_A)
UPDATE CTEB
SET XA.modify('insert sql:column("XB") as first into (/TableA)[1]');
WITH CTEC (PK_A, XA, XC)
AS (SELECT A.PK_A,
a.XA,
c.XC
FROM @A AS a
INNER JOIN
@C AS c
ON c.FK_A = a.PK_A)
UPDATE CTEC
SET XA.modify('insert sql:column("XC") as first into (/TableA)[1]');
SELECT * FROM @A;
这仅使用表 B 和表 C 中的第一个 XML 片段更新 XML。
更新:对于可能遇到此问题的任何人,请查看@Shnugo 的答案以及标记的答案。两种方法都很完美。我将@gofr1 的解决方案标记为答案,仅仅是因为他是第一个回复的。未来任务猎人的另一个考虑因素是您是否喜欢 CTE 或子选择(正如 Shnugo 指出的那样)。