2012-02-10 46 views
6

Hãy nói rằng tôi có hai miếng sau của XML trong cơ sở dữ liệu của tôiKết hợp XML trong một SQL Server

<!-- 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> 

Những thông tin này được lưu trữ trong hai bảng riêng biệt bằng cách sử dụng XML datatype, bổ sung cột XML này được liên kết với một schema mô tả định dạng của xml dự kiến ​​ví dụ

[PairData] [xml](CONTENT [foo].[Pairs]) NULL 

trong một thủ tục/chức năng lưu trữ tôi muốn hợp nhất hai cấu trúc XML như sau:

mục

a, b 

từ mảnh thứ hai của xml, chúng tôi đã thực hiện::

<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> 

mục Vì vậy, từ phần đầu tiên của xml chúng tôi đã đưa

c, d, e 

Chú ý rằng hai mảnh của XML có một mục chung với khóa:

c 

Trong trường hợp này, giá trị từ xml 2 nên được sử dụng trong quá trình hợp nhất xml (loại bỏ giá trị từ xml 1). Một trường hợp khác là XML 1 hoặc 2 có thể là NULL do đó quá trình hợp nhất nên xử lý điều này và đơn giản là trả về giá trị còn lại. Hoặc cả hai có thể là NULL, trong đó trường hợp NULL được trả về.

Ngoài ra, trong thực hiện hiện tại, chúng tôi sẽ trả về cả hai tài liệu XML từ DB và thực hiện hợp nhất mã. Tuy nhiên chúng tôi muốn có sự hợp nhất này được thực hiện trong DB như nhiều quá trình không liên quan được gọi là proc này.

+0

Câu trả lời tùy thuộc vào lưu trữ dữ liệu. (ví dụ: nguồn của bạn là một bảng, một cột xml hoặc một chuỗi ký tự). Sẽ tốt hơn nếu bạn có thể cung cấp thêm thông tin. –

+0

Chúc mừng nhận xét, câu hỏi được cập nhật. – MrEyes

Trả lời

5

Sử dụng:

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') 

Output:

<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> 

UPDATE:

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') 
+0

Điều đó hoạt động hoàn hảo, chỉ một câu hỏi nhỏ làm thế nào tôi sẽ đi về việc thay đổi điều đó để nó được lựa chọn từ các bảng chứ không phải là các vars được khai báo. – MrEyes

+0

@MrEyes, tôi đã cập nhật câu trả lời của mình. –

1

Ví dụ với bảng:

012.
CREATE TABLE #x1 (row_key int, source_xml xml) 
CREATE TABLE #x2 (row_key int, source_xml xml) 

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 1 e value</item> 
</pairs>' 

INSERT INTO #x1 VALUES (1, @x1) 
INSERT INTO #x2 VALUES (1, @x2) 

SELECT 
    ISNULL(a.item_key, b.item_key) [@key] 
    ,ISNULL(b.item_value, a.item_value) [text()] 
FROM 
(
SELECT 
    b.value('@key', 'char(1)') item_key, b.value('.', 'nvarchar(100)') item_value 
FROM 
    #x1 cross apply #x1.source_xml.nodes('./pairs/item') a(b) 
WHERE 
    row_key = 1 
) a 
FULL JOIN 
( 
SELECT 
    b.value('@key', 'char(1)') item_key, b.value('.', 'nvarchar(100)') item_value 
FROM 
    #x2 cross apply #x2.source_xml.nodes('pairs/item') a(b) 
WHERE 
    row_key = 1 
) b 
ON 
    a.item_key = b.item_key 
ORDER BY 
    ISNULL(a.item_key, b.item_key) 
FOR XML PATH ('item'), ROOT ('pairs') 

DROP TABLE #x1 
DROP TABLE #x2 
Các vấn đề liên quan