Sqlserver
 sql >> Cơ Sở Dữ Liệu >  >> RDS >> Sqlserver

Các trường hợp sử dụng cho câu lệnh MERGE của máy chủ SQL:Đồng bộ hóa bảng lịch sử và trực tuyến

GIỚI THIỆU

Câu lệnh SQL Server MERGE là một công cụ cực kỳ hữu ích để thực hiện các hoạt động DML dựa trên việc so sánh hai bảng hoặc hai tập dữ liệu. Cách sử dụng câu lệnh này thực sự giống như thực hiện nhiều thao tác trong một câu lệnh.

Bài viết này sẽ khám phá ba trường hợp sử dụng liên quan đến việc đảm bảo dữ liệu giữa bảng trực tuyến và bảng lịch sử được đồng bộ hóa.

Hãy mô tả tình huống trong một vài câu lệnh phác thảo mà sẽ quen thuộc với nhiều DBA hoặc nhà phát triển:

  1. Bảng nguồn có tên là Tran nắm bắt các giao dịch đang diễn ra trong thời gian thực.
  2. Khoảng thời gian lưu giữ đã thỏa thuận cho bảng Tran là một tháng. Trân phải được thanh trừng vào cuối mỗi tháng.
  3. Hàng ngày, dữ liệu của Tran phải được chuyển sang TranHistory trong quá trình "Cuối ngày".
  4. TranHistory bảng là một bảng lịch sử tổng hợp dữ liệu giao dịch trong hơn một năm.
  5. Tất cả các phụ trang và cập nhật trên Tran bảng phải phản ánh trong TranHistory vào cuối mỗi ngày.

CHUẨN BỊ KỊCH BẢN

Kịch bản được mô tả ở trên ngụ ý rằng các bản ghi trong bảng Tran cũng tồn tại trong bảng TranHistory cho đến khi chúng được xóa hàng tháng. Mỗi ngày, sẽ có một vài bản ghi mới trong bảng Tran nhưng KHÔNG có trong bảng TranHistory. Chúng ta phải tìm cách chèn những hàng mới này.

Trước tiên, chúng ta hãy chuẩn bị các bảng được đề cập (Xem Liệt kê 1 và 2).

  - Liệt kê 1:Tạo Tran TableUSE AUGOCREATE TABLE [Tran] (responseId int NOT NULL, senderId varchar (15), msisdn varchar (15), [message] varbinary, status smallint, application varchar, dấu thời gian gotTime NULL, đã xử lýTime datetime2 NULL, flag smallint, requestDelivery smallint, smallint đã phân phối, tài khoản varchar (20), srcTon smallint, srcNpi smallint, destTon smallint, destNpi smallint, errorCode smallint, messageId varchar, serialNo int, retries smal (20), varchar số lượng lớn (20))  
  - Liệt kê 2:Tạo TranHistory TableUSE AUGOCREATE TABLE [TranHistory] (responseId int NOT NULL, senderId varchar (15), msisdn varchar (15), [message] varchar (160), status smallint, application varchar , đã nhận được, thời gian datetime2 NULL, đã xử lýTime datetime2 NULL, smallint cờ, requestDelivery smallint, smallint đã phân phối, tài khoản varchar (20), srcTon smallint, srcNpi smallint, destTon smallint, destNpi smallint, errorCode smallint, messageId int ,charries, serialNo int , userId varchar (20), buli varchar (20), archivedTime datetime2 NOT NULL,)  

KHI CHƯA ĐƯỢC KẾT HỢP THÌ CHÈN

Sử dụng mã trong Liệt kê 3, chúng tôi chèn một vài hàng trong bảng Tran để bắt đầu. Sau đó, chúng tôi tiếp tục sử dụng câu lệnh MERGE để di chuyển dữ liệu vào bảng TranHistory.

  - Liệt kê 3:Chèn Tập hợp Hàng ban đầu trong Tran TableUSE [AU] GOINSERT INTO [dbo]. [Tran] VALUES (8000, '0233456789', 'Chúc bạn Năm Mới Hạnh phúc', 1, 'K', '20201110 15:00:00', '20201110 15:10:00', 1,1,1, 'KAIROS', 1,2,3,4,1,1,9789,2,1, 'ROUTEMOBILE', '9988776'), (7777, '0233456789', 'Phước hạnh của Chúa ở cùng bạn', 1, 'K', '20201110 08:00:00', '20201110 08:10:00' , 1,1,1, 'KAIROS', 1,2,3,4,1,1,9789,2,1, 'ROUTEMOBILE', '9988776'), (7005, '0234876789', 'Chúc mừng sinh nhật bạn ', 1,' K ',' 20201110 09:00:00 ',' 20201110 09:20:00 ', 1,1,1,' KAIROS ', 1,2,3,4,1,1,9789, 2,1, 'ROUTEMOBILE', '9988776'), (9002, '0233456789', 'Merry Christmas', 1, 'K', '20201110 07:00:00', '20201110 07:15:00', 1 , 1,1, 'KAIROS', 1,2,3,4,1,1,9789,2,1, 'ROUTEMOBILE', '9988776'), (6789, '0233467889', 'Mua ô tô hoàn toàn mới của chúng tôi cho dưới $ 8000 ', 1,' K ',' 20201110 14:00:00 ',' 20201110 14:20:00 ', 1,1,1,' KAIROS ', 1,2,3,4,1,1 , 9789,2,1, 'ROUTEMOBILE', '9988776'), (7685, '0244556789', 'Chúc mừng tháng mới. Chúa phù hộ và gia tăng bạn', 1, 'K', '20201 110 17:00:00 ',' 20201110 17:08:00 ', 1,1,1,' KAIROS ', 1,2,3,4,1,1,9789,2,1,' ROUTEMOBILE ',' 9988776 '), (4983,' 0229856789 ',' Hôm nay có sự giúp đỡ của bạn! ', 1,' K ',' 20201110 19:00:00 ',' 20201110 19:20:00 ', 1,1,1 , 'KAIROS', 1,2,3,4,1,1,9789,2,1, 'ROUTEMOBILE', '9988776'), (6879, '0239986789', 'Hãy gọi cho chúng tôi cho dự án tái định cư tiếp theo của bạn', 1 , 'K', '20201110 19:15:00', '20201110 19:20:00', 1,1,1, 'KAIROS', 1,2,3,4,1,1,9789,2,1 , 'ROUTEMOBILE', '9988776'), (4567, '0233456789', 'Làm việc chăm chỉ luôn trả tiền', 1, 'K', '20201110 22:05:00', '20201110 22:20:00', 1, 1,1, 'KAIROS', 1,2,3,4,1,1,9789,2,1, 'ROUTEMOBILE', '9988776'), (8890, '0244656733', 'Đừng đợi mua đất, mua đất và đợi ', 1,' K ',' 20201110 15:05:00 ',' 20201110 15:20:00 ', 1,1,1,' KAIROS ', 1,2,3,4, 1,1,9789,2,1, 'ROUTEMOBILE', '9988776'), (6789, '0233466734', 'Chúng tôi đang chuyển địa điểm. Gọi cho chúng tôi theo số 077788997 ', 1,' K ',' 20201110 18:02:00 ',' 20201110 18:17:00 ', 1,1,1,' KAIROS ', 1,2,3,4,1, 1,9789,2,1, 'ROUTEMOBILE', '9988776'), (9899, ​​'0233456556', 'Xem phim mới nhất của chúng tôi', 1, 'K', '20201110 06:00:00', '20201110 06:02:00 ', 1,1,1,' KAIROS ', 1,2,3,4,1,1,9789,2,1,' ROUTEMOBILE ',' 9988776 '), (6789,' 0233456338 ' , 'Chúng tôi ở đây để làm bạn hạnh phúc', 1, 'K', '20201110 12:16:00', '20201110 12:20:00', 1,1,1, 'KAIROS', 1,2,3 , 4,1,1,9789,2,1, 'ROUTEMOBILE', '9988776') ĐI  

Chúng tôi có thể làm điều này theo một cách đơn giản hơn nhiều, nhưng chúng tôi muốn hiển thị cú pháp câu lệnh MERGE (Xem Liệt kê 4):

  - Liệt kê 4:Hợp nhất các bản ghi trong Tran Table thành TranHistory TableMERGE VÀO [TranHistory] a SỬ DỤNG [Tran] bON a.responseId =b.responseID KHÔNG ĐƯỢC PHÉP THEO MỤC TIÊU SAU ĐÓ CHÈN ([responseId], [senderId] , [msisdn], [nội dung], [trạng thái], [ứng dụng], [Thời gian nhận], [Thời gian xử lý], [cờ], [Yêu cầu giao hàng], [đã giao], [tài khoản], [srcTon], [srcNpi], [ destTon], [destNpi], [errorCode], [messageId], [sequenceNo], [retries], [messagePosystem], [userId], [số lượng lớn], [archivedTime]) GIÁ TRỊ ([responseId], [senderId], [ msisdn], [tin nhắn], [trạng thái], [ứng dụng], [thời gian nhận], [thời gian xử lý], [cờ], [yêu cầu giao hàng], [đã gửi], [tài khoản], [srcTon], [srcNpi], [destTon] , [destNpi], [errorCode], [messageId], [sequenceNo], [retries], [messagePosystem], [userId], [BulId], getdate ()); ĐI  

Tuyên bố MERGE cho biết:

  1. Lấy nội dung của bảng [Tran] và so sánh chúng với bảng [TranHistory] dựa trên responseId cột.
  2. Chèn những hàng bạn tìm thấy trong bảng nguồn nhưng không tìm thấy trong bảng đích (TranHistory).

Như hiện tại, Tran và TranHistory đang ở mỗi. Nhưng giả sử ngày hôm sau, các hàng mới được giới thiệu trong Bảng chuyển đổi. Chúng ta cũng phải đẩy chúng vào bảng TransHistory trong khi vẫn giữ lại các bản ghi trong bảng Tran cho đến khi hết tháng.

Chúng tôi lại sử dụng script trong danh sách 4. Lần này, chúng tôi thêm một mệnh đề OUTPUT để cho biết những gì đã được giới thiệu (Xem Liệt kê 5):

« [responseId], [senderId], [msisdn], [message], [trạng thái], [ứng dụng], [thời gian nhận], [thời gian xử lý], [cờ], [requestDelivery], [đã giao], [tài khoản], [srcTon ], [srcNpi], [destTon], [destNpi], [errorCode], [messageId], [sequenceNo], [retries], [messagePosystem], [userId], [số lượng lớn], [archivedTime]) GIÁ TRỊ ([responseId ], [senderId], [msisdn], [tin nhắn], [trạng thái], [ứng dụng], [Thời gian nhận], [Thời gian xử lý], [cờ], [requestDelivery], [đã giao], [tài khoản], [srcTon], [srcNpi], [destTon], [destNpi], [errorCode], [messageId], [sequenceNo], [retries], [messagePosystem], [userId], [BulId], getdate ()) OUTPUT đã bị xóa. *, $ hành động, đã chèn. *; GO

Chúng tôi có thể lặp lại quá trình này sau khi giới thiệu các hàng bổ sung vào bảng Tran (Liệt kê 6 và 7) và chúng tôi nhận được hành vi tương tự:

  - Liệt kê 6:Chèn sáu hàng mới trong Tran TableUSE [AU] GOINSERT INTO [dbo]. [Tran] VALUES (6879, '0239986789', 'Hãy gọi cho chúng tôi cho dự án tái định cư tiếp theo của bạn', 1, 'K', '20201110 19:15:00', '20201110 19:20:00', 1,1,1, 'KAIROS', 1,2,3,4,1,1,9789,2,1, 'ROUTEMOBILE', '9988776'), (4567, '0233456789', 'Làm việc chăm chỉ luôn trả tiền', 1, 'K', '20201110 22:05:00', '20201110 22:20:00', 1,1 , 1, 'KAIROS', 1,2,3,4,1,1,9789,2,1, 'ROUTEMOBILE', '9988776'), (8890, '0244656733', 'Đừng đợi mua đất , mua đất và đợi ', 1,' K ',' 20201110 15:05:00 ',' 20201110 15:20:00 ', 1,1,1,' KAIROS ', 1,2,3,4,1 , 1,9789,2,1, 'ROUTEMOBILE', '9988776'), (6789, '0233466734', 'Chúng tôi đang chuyển địa điểm. Hãy gọi cho chúng tôi theo số 077788997', 1, 'K', '20201110 18:02:00' , '20201110 18:17:00', 1,1,1, 'KAIROS', 1,2,3,4,1,1,9789,2,1, 'ROUTEMOBILE', '9988776'), (9899, '0233456556', 'Xem phim mới nhất của chúng tôi', 1, 'K', '20201110 06:00:00', '20201110 06:02:00', 1,1,1, 'KAIROS', 1,2 , 3,4,1,1,9789,2,1, 'ROUTEMOBILE', '9988776'), (6789, '0233456338', 'Chúng tôi ở đây để làm cho bạn hạnh phúc', 1, 'K', '2020 1110 12:16:00 ',' 20201110 12:20:00 ', 1,1,1,' KAIROS ', 1,2,3,4,1,1,9789,2,1,' ROUTEMOBILE ',' 9988776 ') ĐI  
  - Liệt kê 7:Chèn thêm ba hàng trong Tran TableUSE [AU] GOINSERT INTO [dbo]. [Tran] VALUES (7789, '0233456433', 'Bạn đã sẵn sàng cho cấp độ tiếp theo chưa?', 1, 'K', '20201110 14:35:00', '20201110 14:40:00', 1,1,1, 'KAIROS', 1,2,3,4,1,1,9789,2,1, 'ROUTEMOBILE', '9988776'), (8000, '0233457759', 'Hutchies Honey, một cấp độ khác của hương vị ', 1,' K ',' 20201110 08:00:00 ',' 20201110 08:08:00 ', 1,1,1,' KAIROS ', 1,2,3,4,1,1, 9789,2,1, 'ROUTEMOBILE', '9988776'), (7777, '0233458909', 'Hãy chắc chắn rằng bạn bỏ phiếu vào ngày mai', 1, 'K', '20201110 09:45:00', '20201110 09:50 :00 ', 1,1,1,' KAIROS ', 1,2,3,4,1,1,9789,2,1,' ROUTEMOBILE ',' 9988776 '), (9890,' 0233459994 ',' Chúc chúc bạn một Giáng sinh vui vẻ ', 1,' K ',' 20201110 10:00:00 ',' 20201110 10:05:00 ', 1,1,1,' KAIROS ', 1,2,3,4,1, 1,9789,2,1, 'ROUTEMOBILE', '9988776') ĐI  

KHI ĐẾN KHI ĐƯỢC CẬP NHẬT

Một trường hợp khác là cập nhật bảng trực tiếp (Tran) khi chúng ta muốn đồng bộ các cập nhật đó với bảng TranHistory. Chúng tôi tạo kịch bản này bằng cách cập nhật các hàng trong bảng Tran bằng cách sử dụng tập lệnh trong Liệt kê 8.

  - Liệt kê 8:Cập nhật và Chèn hàng trong Tran TableUSE AUGOUPDATE [dbo]. [Tran] SET account ='JUNIPER' WHERE account ='KAIROS'; GOINSERT INTO [dbo]. [Tran] VALUES ( 5578, '0233566933', 'Mới nhất trong khối!', 1, 'K', '20201110 14:35:00', '20201110 14:40:00', 1,1,1, 'KAIROS', 1, 2,3,4,1,1,9789,2,1, 'ROUTEMOBILE', '9988776') ĐI  

Hình 6 cho thấy rằng các hàng được cập nhật trong bảng đích. Chúng tôi nhận được chi tiết này bằng cách sử dụng điều khoản OUTPUT.

Chúng ta phải sử dụng mệnh đề được đánh dấu trong Liệt kê 9. Câu lệnh MERGE xác định các hàng phù hợp với điều kiện JOIN và cập nhật dữ liệu trong cột được chỉ định ( tài khoản ). Chúng tôi có thể cập nhật nhiều hàng bằng cách tiếp cận này.

  - Liệt kê 9:Đồng bộ hóa dữ liệu trong TranHistory bằng cách cập nhật RowsUSE AUGOMERGE VÀO [TranHistory] a SỬ DỤNG [Tran] bON a.responseId =b.responseID ĐÃ ĐƯỢC PHÉP THEO ĐẾN KHI CẬP NHẬT a.account =b.account MÀ KHÔNG ĐƯỢC PHÉP THEO MỤC TIÊU SAU ĐÓ CHÈN ([responseId], [senderId], [msisdn], [message], [status], [application], [acceptTime], [processingTime], [flag], [requestDelivery], [delivery], [account] , [srcTon], [srcNpi], [destTon], [destNpi], [errorCode], [messageId], [sequenceNo], [retries], [messagePosystem], [userId], [BulId], [archivedTime]) GIÁ TRỊ ([responseId], [senderId], [msisdn], [tin nhắn], [trạng thái], [ứng dụng], [thời gian nhận], [thời gian xử lý], [cờ], [yêu cầu giao hàng], [đã giao], [tài khoản], [ srcTon], [srcNpi], [destTon], [destNpi], [errorCode], [messageId], [sequenceNo], [retries], [messagePosystem], [userId], [BulId], getdate ()) OUTPUT đã bị xóa. *, $ action, đã được chèn. *; GO  

KHI KHÔNG ĐƯỢC NGUỒN PHỐI HỢP VỚI NGUỒN THÌ XÓA

Một kịch bản khác liên quan đến việc các hàng bị xóa khỏi bảng nguồn (Liệt kê 10). Khi điều này xảy ra, chúng tôi phải xác định các hàng không còn tồn tại trong bảng nguồn và xóa chúng khỏi bảng đích.

Chúng tôi thực hiện điều này bằng cách sử dụng mệnh đề được đánh dấu trong Liệt kê 10. Một lần nữa, Hình 7 và 8 cho thấy các hàng bị ảnh hưởng bởi câu lệnh MERGE này.

  - Liệt kê 10:Cập nhật và chèn hàng trong Tran TableUSE AUGODELETE FROM [dbo]. [Tran] WHERE account ='JUNIPER'; GO  
  - Liệt kê 11:Đồng bộ hóa các bảng sau khi xóa khỏi Tran TableUSE AUGOMERGE VÀO [TranHistory] a SỬ DỤNG [Tran] bON a.responseId =b.responseID KHI KHÔNG ĐƯỢC PHÉP THEO NGUỒN NÊN XÓA BẰNG NGUỒN GỐC KHI CẬP NHẬT a.account =b tài khoản. đã phân phối], [tài khoản], [srcTon], [srcNpi], [destTon], [destNpi], [errorCode], [messageId], [sequenceNo], [retries], [messagePosystem], [userId], [BulId] , [archivedTime]) VALUES ([responseId], [senderId], [msisdn], [message], [status], [application], [secureTime], [processingTime], [flag], [requestDelivery], [delivery] , [tài khoản], [srcTon], [srcNpi], [destTon], [destNpi], [errorCode], [messageId], [sequNo], [retries], [messagePosystem], [userId], [BulId], getdate ()) OUTPUT đã bị xóa. *, $ Action, được chèn. *; GO  

Hình 7 cho thấy các hàng đã bị xóa và Hình 8 cho thấy các hàng đã được cập nhật. Đó là sức mạnh của câu lệnh MERGE. Chúng tôi có thể thực hiện tất cả các thao tác xóa, chèn và cập nhật trong một câu lệnh.

KẾT LUẬN

Bài viết này đã xem xét việc sử dụng câu lệnh MERGE để đồng bộ hóa dữ liệu giữa bảng trực tuyến và bảng lịch sử trong khi vẫn duy trì lưu giữ mong muốn được yêu cầu trong cả hai bảng.

Có nhiều trường hợp sử dụng khác cho câu lệnh SQL Server MERGE không được đề cập trong bài viết này, nhưng chúng được khám phá trong tài liệu của Microsoft. Dữ liệu nguồn được chỉ định trong mệnh đề USING không giới hạn trong các bảng. Tập kết quả từ các câu lệnh SELECT rõ ràng có thể là dữ liệu nguồn. Biểu thức bảng phổ biến cũng có thể là dữ liệu nguồn.

TÀI LIỆU THAM KHẢO

MERGE trong Transact-SQL


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Spotlight Cloud Basic:Công cụ giám sát hiệu suất cơ sở dữ liệu miễn phí tốt nhất

  2. Buộc hết thời gian chờ truy vấn trong SQL Server

  3. SQL Server:Tôi có nên sử dụng bảng information_schema trên bảng sys không?

  4. Khám phá giao diện cửa hàng truy vấn SQL Server 2016

  5. Tham gia loại bỏ:Khi máy chủ SQL loại bỏ các bảng không cần thiết