2013-08-09 82 views
5

Tôi cần hợp nhất dữ liệu từ bảng nhà tài trợ thành hai bảng đích. Cấu trúc như sau. Nếu không tìm thấy projid trong bảng theo dõi, tôi cần tạo thành phần mới trong bảng thành phần và sử dụng id mới để chèn vào bảng theo dõi. Ngoài ra, đối với những mục không còn tồn tại trong bảng nhà tài trợ, cột theo dõi 'hoạt động' phải được đánh dấu 0. Tôi có thể đạt được điều này trong một câu lệnh hợp nhất không?Hợp nhất dữ liệu vào hai bảng đích

tài trợ Bảng

projid  | datestamp | Ownerid 
------------------------------------------------- 
c_abc  1-jan-2013  name1 
c_def  2-jan-2013  name3 
c_ghi  3-jan-2013  name4 

dấu vết bàn

compid  |projid  |active | ... 
----------------------------------------------- 
123   c_abc  1 
124   c_xyz  1 
125   c_def  1 

thành phần bảng

compid  |ownerid 
------------------------- 
123  name1 
124  name2 
125  name3 

BẢNG OUTPUT SAU MERGE:

bảng thành phần

compid  |ownerid 
------------------------- 
123  name1 
124  name2 
125  name3 
126  name4 

bảng dấu vết

compid  |projid  |active | ... 
----------------------------------------------- 
123   c_abc  1 
124   c_xyz  0 
125   c_def  1 
126   c_ghi  1 
+0

'Tên4' đến từ đâu? –

+0

name4 đến từ bảng nhà tài trợ cũng như – mhn

+0

@mhn - bạn có nói rằng có một cột khác trong bảng nhà tài trợ có chứa văn bản đó không? Nếu có, bạn có thể thêm nó vào ví dụ của mình không? –

Trả lời

5

Về mặt lý thuyết, cần có một giải pháp để làm điều này trong bản Tuyên Bố duy nhất, nhưng tôi có cho đến nay đã không tìm thấy nó. *

Sau đây là cách nó có thể được thực hiện với hai MERGE báo cáo:

WITH CTE_trgt AS 
(
    SELECT c.compid, c.ownerid, t.projid, t.active 
    FROM component c 
    INNER JOIN trace t ON c.compid = t.compid 
) 
MERGE CTE_trgt t 
USING Donor s 
ON t.projid = s.projid 
WHEN NOT MATCHED BY TARGET 
    THEN INSERT (ownerid) 
    VALUES (s.ownerid) 
OUTPUT 
    INSERTED.compid, s.projid, 1 INTO trace; 


MERGE trace t 
USING Donor s 
ON t.projid = s.projid 
WHEN NOT MATCHED BY SOURCE 
    THEN UPDATE SET t.active = 0; 

SQLFiddle DEMO


* Phần với việc cập nhật tích cực cột:

WHEN NOT MATCHED BY SOURCE 
    THEN UPDATE SET t.active = 0 

nên có thể phù hợp trong truy vấn trên tạo ra một single merge statement cho tất cả các hoạt động, nhưng nó ném một lỗi:

View or function 't' is not updatable because the modification affects multiple base tables

ngay cả khi nó rõ ràng là cột duy nhất, và regular non-merge update works fine. Có thể ai đó biết lý do và/hoặc giải pháp cho việc này.

+0

Xin chào Nenad, cảm ơn rất nhiều về đầu vào của bạn !! câu lệnh hợp nhất đầu tiên đã ổn. Nhưng tuyên bố cập nhật cờ hoạt động trong bảng theo dõi tôi không thể tùy chỉnh theo cách tôi muốn. Tôi đã bỏ lỡ một nhà tài trợ cột khác trong dấu vết. Vì vậy, tôi cần phải cập nhật chỉ những hàng mà donorid = 'MyDonorId'. Tôi không thể đáp ứng điều khoản này ở bất kỳ đâu trên câu lệnh hợp nhất. tôi đã thử – mhn

+0

... MERGE (chọn * từ dấu vết nơi donorid = 'MyDonorId') t SỬ DỤNG Nhà tài trợ s TRÊN t.projid = s.projid KHI KHÔNG PHÙ HỢP VỚI NGUỒN THEN UPDATE SET t.active = 0; Nó nói cú pháp xấu: ( – mhn

+0

@mhn Bạn có thể sử dụng biểu thức bảng chung - Cú pháp 'WITH CTE', như trong câu lệnh đầu tiên để lọc mục tiêu –