2012-04-18 22 views
35

Sau đây:T SQL hợp nhất ví dụ cần thiết để giúp hiểu

MERGE dbo.commissions_history AS target 
USING (SELECT @amount, @requestID) AS source (amount, request) 
ON (target.request = source.request) 
WHEN MATCHED THEN 
    UPDATE SET amount = source.amount 
WHEN NOT MATCHED THEN 
    INSERT (request, amount) 
    VALUES (source.request, source.amount); 

từ https://stackoverflow.com/a/2967983/857994 là một cách khá tiện lợi để làm chèn/cập nhật (và xóa với một số công việc thêm vào). Tôi đang tìm kiếm nó khó khăn để làm theo mặc dù ngay cả sau khi một số googling.

Có thể ai đó xin vui lòng:

  • giải thích điều này một chút trong thuật ngữ đơn giản - tài liệu MSDN cắt xẻo bộ não của tôi trong trường hợp này.
  • chỉ cho tôi cách có thể sửa đổi để người dùng có thể nhập giá trị cho số tiền & yêu cầu thay vì yêu cầu họ chọn từ một vị trí cơ sở dữ liệu khác?

Về cơ bản, tôi muốn sử dụng tính năng này để chèn/cập nhật từ ứng dụng C# với thông tin được lấy từ các tệp XML mà tôi nhận được. Vì vậy, tôi cần phải hiểu làm thế nào tôi có thể xây dựng một truy vấn bằng tay để có được dữ liệu phân tích cú pháp của tôi vào cơ sở dữ liệu với cơ chế này.

+0

Tôi đã đưa ra hướng dẫn bên dưới nhưng nếu tôi là bạn, tôi sẽ đăng câu hỏi thứ hai tại đây o n SO có cấu trúc của bảng mục tiêu của bạn và một đoạn mã mẫu từ nguồn xml của bạn và hỏi ... làm thế nào tôi viết một câu lệnh MERGE để cập nhật bảng này từ xml này. Cũng nên nhớ rằng một tuyên bố MERGE cuối cùng có thể thậm chí không phải là công cụ tốt nhất cho công việc. – RThomas

+0

Cảm ơn bạn, đó thực sự là những gì tôi cần. Tôi có thể đặt câu hỏi thêm sau đó, đó là một gợi ý tốt. –

Trả lời

67

Nếu bạn không quen thuộc với join statements thì đó là nơi bạn cần bắt đầu. Hiểu cách thức hoạt động của join là chìa khóa cho phần còn lại. Khi bạn đã quen với việc tham gia thì việc hiểu sự hợp nhất là dễ nhất bằng cách suy nghĩ về việc kết hợp hoàn toàn với các hướng dẫn về những việc cần làm cho các hàng có hoặc không khớp.

Vì vậy, bằng cách sử dụng mẫu mã được cung cấp cho phép nhìn vào bảng commissions_history

| Amount | Request | <other fields | 
-------------------------------------------- 
| 12.00 | 1234  | <other data | 
| 14.00 | 1235  | <other data | 
| 15.00 | 1236  | <other data | 

Những tuyên bố hợp nhất tạo ra một đầy đủ tham gia giữa một bảng, gọi là "mục tiêu" và một biểu thức trả về một bảng (hoặc một tập hợp kết quả tương tự như một bảng giống như một CTE) được gọi là "nguồn".

Trong ví dụ được cho, đó là sử dụng các biến làm nguồn mà chúng tôi giả định đã được người dùng đặt hoặc được chuyển làm tham số.

DECLARE @Amount Decimal = 18.00; 
DECLARE @Request Int = 1234; 

MERGE dbo.commissions_history AS target  
USING (SELECT @amount, @requestID) AS source (amount, request)  
ON (target.request = source.request) 

Tạo kết quả sau khi được nghĩ là tham gia.

| Amount | Request | <other fields | Source.Amount | Source.Request | 
------------------------------------------------------------------------------ 
| 12.00 | 1234  | <other data | 18.00  |  1234  | 
| 14.00 | 1235  | <other data | null  |  null  | 
| 15.00 | 1236  | <other data | null  |  null  | 

Sử dụng hướng dẫn về những gì cần làm cho mục tiêu trong điều kiện tìm thấy kết quả phù hợp.

WHEN MATCHED THEN   
UPDATE SET amount = source.amount  

Bảng mục tiêu kết quả bây giờ sẽ trông như thế này. Hàng có yêu cầu 1234 được cập nhật thành 18.

| Amount | Request | <other fields | 
-------------------------------------------- 
| 18.00 | 1234  | <other data | 
| 14.00 | 1235  | <other data | 
| 15.00 | 1236  | <other data | 

Vì một trận đấu WAS không tìm thấy gì khác xảy ra. Nhưng cho phép nói rằng các giá trị từ nguồn là như thế này.

DECLARE @Amount Decimal = 18.00; 
DECLARE @Request Int = 1239; 

Các kết quả tham gia sẽ trông như thế này:

| Amount | Request | <other fields | Source.Amount | Source.Request | 
------------------------------------------------------------------------------ 
| 12.00 | 1234  | <other data | null  |  null  | 
| 14.00 | 1235  | <other data | null  |  null  | 
| 15.00 | 1236  | <other data | null  |  null  | 
| null | null  | null   | 18.00  |  1239  | 

Kể từ khi một dòng tương ứng không được tìm thấy trong các mục tiêu báo cáo kết quả thực hiện các điều khoản khác.

WHEN NOT MATCHED THEN         
INSERT (request, amount)         
VALUES (source.request, source.amount); 

Kết quả trong một bảng mục tiêu mà bây giờ trông như thế này:

| Amount | Request | <other fields | 
-------------------------------------------- 
| 12.00 | 1234  | <other data | 
| 14.00 | 1235  | <other data | 
| 15.00 | 1236  | <other data | 
| 18.00 | 1239  | <other data | 

Các báo cáo hợp nhất tiềm năng thực sự là khi nguồn và mục tiêu là cả hai bảng lớn. Vì nó có thể thực hiện một số lượng lớn các bản cập nhật và/hoặc chèn cho mỗi hàng với một câu lệnh đơn giản.

Lưu ý cuối cùng. Điều quan trọng cần lưu ý là not matched mặc định là toàn bộ khoản not matched by target, tuy nhiên bạn có thể chỉ định not matched by source thay cho, hoặc ngoài, mệnh đề mặc định. Câu lệnh phối hợp hỗ trợ cả hai loại không phù hợp (các bản ghi trong nguồn không có trong đích, hoặc các bản ghi trong đích không có trong mã nguồn như được định nghĩa bởi điều khoản trên). You can find full documentation, restrictions, and complete syntax on MSDN.

+4

Câu trả lời hay, cảm ơn! –

+0

'FULL JOIN' có thể làm những điều tuyệt vời! – ErikE

+0

Câu trả lời hay, rất kỹ lưỡng. Tôi luôn muốn chỉ định 'B TARNG MỤC TIÊU' hoặc 'B SONG NGUỒN' với mệnh đề WHEN NOT MATCHED, vì nó rõ ràng hơn khi đọc lại nó theo dõi. Bạn không cần phải ghi nhớ những gì mặc định là, và nó gần gũi hơn với tiếng Anh. – Davos

0

Trong ví dụ câu trả lời cho bạn đã làm

DECLARE @Request Int 

, nhưng gọi nó trong SQL như sau:

SELECT @amount, @requestID 

khác sẽ được đặt tên và gọi biến hệt:

@amount vs. Amount -> @Amount & Amount 
Các vấn đề liên quan