2012-04-30 29 views
7

Tôi không biết bắt đầu từ đâu hoặc cách thức này sẽ hoạt động và tôi hy vọng ai đó có ý tưởng hoặc phương pháp đã được chứng minh.Cách tạo truy vấn chỉ nhận dữ liệu đã được cập nhật trong bảng

Để hiển thị ví dụ về những gì tôi đang cố gắng làm, tôi đã tạo một thủ tục được lưu trữ CẬP NHẬT hoặc INSERT bản ghi mới trong bảng Địa phương bằng cách lấy bản ghi từ bảng liên kết. Thủ tục lưu trữ chạy như một công việc trong SQL Server để cập nhật và chèn bản ghi mới.

Câu hỏi của tôi là: Có cách nào để truy vấn dữ liệu trong Bảng cục bộ để Ban đầu tôi có thể nhận tất cả các bản ghi nhưng không chỉ nhận được bản ghi mới đã được chèn vào hoặc bản ghi cũ được cập nhật?

Tôi không muốn liên tục nhận tất cả các bản ghi, chỉ các bản ghi mới được thêm hoặc bản ghi được cập nhật.

Điều này có khả thi không?

Đây là thủ tục lưu trữ Tôi ave tạo ra như là một ví dụ để cập nhật các dữ liệu điện thoại địa phương:

CREATE PROCEDURE sp_UPDATE_PHONE_RECORDS 
AS 
BEGIN 
MERGE dbo.PHONE_REC AS Target 
USING (SELECT MEMBER_ID 
     ,HOME_PHONE = dbo.udf_StdPhoneFmt(HOME) 
     ,CELL_PHONE = dbo.udf_StdPhoneFmt(CELL) 
     ,WORK_PHONE = dbo.udf_StdPhoneFmt(WORK) 

FROM PHONE WHERE MEMBER_ID IS NOT NULL) AS SOURCE 

ON (Target.MEMBER_ID = SOURCE.MEMBER_ID) 

WHEN MATCHED THEN 

    UPDATE SET Target.HOME_PHONE = Source.HOME_PHONE,Target.CELL_PHONE = Source.CELL_PHONE, 
    Target.WORK_PHONE = Source.WORK_PHONE 

WHEN NOT MATCHED BY TARGET THEN 
    INSERT (MEMBER_ID, HOME_PHONE, CELL_PHONE ,WORK_PHONE) 

    VALUES (Source.MEMBER_ID, Source.HOME_PHONE, Source.CELL_PHONE, Source.WORK_PHONE); 
END 
GO 

Đây có phải là có thể?

Cảm ơn tất cả mọi người!

+1

Nó cảm thấy như [ Sao chép SQL Server] (http://msdn.microsoft.com/en-us/library/ms151198.aspx) là công cụ thích hợp cho điều này –

Trả lời

6

Điều chúng tôi thường làm là thêm hai trường ngày/giờ vào bảng nguồn, giống như Source.LastModifiedOn và Source.CreatedOn.

Sau đó, khi công việc chạy để cập nhật bảng mục tiêu, bạn có thể nói cho tôi tất cả các hàng Source.LastModifiedOn và Source.CreatedOn kể từ lần cuối cùng công việc chạy và thực hiện cập nhật/chèn dựa trên các hàng.

Tất nhiên bạn sẽ cần đảm bảo Source.LastModifiedOn và Source.CreatedOn được thiết lập chính xác.

+1

Đây là một cách tiếp cận thú vị. :) Cảm ơn một lần nữa! – Asynchronous

4

Tôi sẽ sử dụng OUTPUT clause với $action cột:

DECLARE @Target TABLE 
(
    Id INT NOT NULL, 
    Value VARCHAR(10) NULL 
); 
INSERT @Target 
VALUES (1, 'A'), (2, NULL), (3, NULL);  
DECLARE @Source TABLE 
(
    Id INT NOT NULL, 
    Value VARCHAR(10) NULL 
); 
INSERT @Source 
VALUES (2, 'B'), (4, 'D'), (5, 'E'); 
DECLARE @AffectedRows TABLE 
(
    MergeAction  NVARCHAR(10) NOT NULL, 
    Old_Id   INT NULL, 
    Old_Value  VARCHAR(10) NULL, 
    New_Id   INT NULL, 
    New_Value  VARCHAR(10) NULL 
); 

MERGE @Target t 
USING @Source s ON t.Id = s.Id 
WHEN MATCHED THEN 
     UPDATE SET Value = s.Value 
WHEN NOT MATCHED THEN 
     INSERT (Id, Value) VALUES (s.Id, s.Value) 
OUTPUT $action, deleted.Id, deleted.Value, inserted.Id, inserted.Value 
     INTO @AffectedRows(MergeAction, Old_Id, Old_Value, New_Id, New_Value); 

SELECT * FROM @Target; 
SELECT * FROM @AffectedRows; 

Kết quả:

Id Value 
-- ----- 
1 A 
2 B <-- updated row 
3 NULL 
4 D <-- inserted row 
5 E <-- inserted row 

MergeAction Old_Id  Old_Value New_Id  New_Value 
----------- ----------- ---------- ----------- --------- 
INSERT  NULL  NULL  4   D 
INSERT  NULL  NULL  5   E 
UPDATE  2   NULL  2   B 
+1

Tôi sẽ làm việc với ví dụ của bạn và trả về với phản hồi, không muốn đánh dấu nó là câu trả lời, chỉ trong trường hợp tôi có câu hỏi khác. Nhưng cảm ơn bạn đã dành thời gian để trả lời. :) – Asynchronous

+0

@UnaverageGuy: Nếu bạn có câu hỏi, sau đó vui lòng hỏi. Nếu tôi biết câu trả lời, thì tôi sẽ giúp bạn. –

0

Bạn có thể viết một Trigger trên bàn địa phương của bạn mà sẽ cháy khi một bản cập nhật hoặc chèn được thực hiện trên nó. Là một phần của logic kích hoạt, bạn phải chèn các bản ghi được cập nhật hoặc mới được chèn vào vào một bảng tạm thời. Đây là cách đơn giản nhất để bạn có thể ghi lại các thay đổi của mình vào bảng cục bộ.

0

này về cơ bản là một biến thể của RDotLee's answer, nhưng nó là một cách tiếp cận khác mà tôi sử dụng đôi khi tôi không quan tâm về ngày thực tế/thời gian khi các hồ sơ được tạo ra:

Tôi chỉ cần thêm một bit lĩnh vực được gọi modified với giá trị mặc định 1.
Nếu hàng mới được chèn vào bảng, modified được đặt thành 1 tự động.
Nếu hàng hiện có được cập nhật, tôi phải đảm bảo rằng modified cũng được đặt thành 1.

Bằng cách đó, công việc chỉ cần tìm kiếm tất cả các hàng có modified = 1.
Không cần theo dõi ngày/giờ khi công việc được thực hiện lần cuối.

Khi công việc đã được thực hiện thành công, điều cuối cùng nó là "thiết lập lại" lĩnh vực modified trong tất cả các hàng:

update TheTable set modified = 0 

IMO, phương pháp này là làm việc ít hơn khi bạn chỉ quan tâm đến rằng sự các hàng đã được sửa đổi kể từ lần chạy công việc cuối cùng, nhưng không được sửa đổi khi chúng được sửa đổi.

Nhưng nó có cùng một bất lợi như phương pháp "LastModifiedOn/CreatedOn" của RDotLee - bạn cần đảm bảo rằng mọi cập nhật trên bảng thực sự đặt cột modified thành 1, vì vậy bạn chỉ có thể sử dụng khi bạn ở kiểm soát tất cả các mã ghi vào bảng.

+0

Được rồi, tôi đã tìm thấy một giải pháp hoạt động, không chắc đó là giải pháp tốt nhất, đó là sự kết hợp các ý tưởng được đăng ở đây. Những gì tôi đã làm là tạo một cột TIME_STAMP trên bảng LOCAL. Điều này thêm một SMALLDATETIME vào các bản ghi (hàng) mỗi lần một bản ghi được cập nhật hoặc khi các bản ghi mới được chèn vào. Bây giờ tôi có thể truy vấn cơ sở bảng cục bộ trên Bản ghi được cập nhật hoặc được chèn vào trong 24 giờ qua hoặc giữa thời gian này và thời gian đó bằng cách sử dụng TIME_STAMP. Làm thế nào tôi có thể đăng lại được mã hóa ở đây? – Asynchronous

+0

@UnaverageGuy Bạn có nghĩa là TimeStamp? Đó không phải là một SmallDateTime. Và tôi đã đăng nó như một câu trả lời 3 giờ trước. – Paparazzi

+0

Không, tôi đã tạo một cột trên Bảng địa phương và đặt tên cột là TIME_STAMP, kiểu dữ liệu là smalldatetime. Điều tôi cần biết bây giờ là làm cách nào để truy vấn bảng cục bộ bằng cách sử dụng datetime trong cột TIME_STAMP để nhận tất cả hồ sơ được chèn hoặc cập nhật giữa thời gian này và thời gian đó. – Asynchronous

0

TimeStamp

Mốc thời gian được tăng lên và chèn hoặc cập nhật.

Trên Thạc sĩ làm cho nó một dấu thời gian và trên Slave làm cho nó một Binary (8)

select [timeStampSlave].* 
from [timeStampSlave] 
join [timeStampMaster] 
on [timeStampSlave].[ID] = [timeStampMaster].ID 
and [timeStampSlave].[timeStamp] < [timeStampMaster].[timestamp] 

Để truy vấn trên các máy chủ, bạn có thể sử dụng cú pháp sau

[MasterSever].[test].[dbo].[timeStampMaster] 
Các vấn đề liên quan