2010-01-29 30 views
6

Tôi có một bảng máy chủ sql có cột dấu thời gian. Có cách nào để buộc cột dấu thời gian thay đổi mà không cần cập nhật bản ghi thực tế không?Cách cập nhật cột dấu thời gian máy chủ sql mà không thay đổi dữ liệu ghi hình

Lý do tôi hỏi là vì tôi muốn dấu thời gian của bản ghi thay đổi khi bản ghi được chèn/cập nhật/xóa trong bảng con.

Dấu thời gian có thể không phải là cách tốt nhất để thực hiện việc này. Nếu không, tôi nên làm gì? Tôi không muốn sử dụng datetime vì tôi không cảm thấy đó là một cách hay để phiên bản. Tôi không muốn sử dụng một số nguyên, bởi vì tôi không muốn phải đọc giá trị để tăng nó.

Đề xuất?

+0

DateTime thường được sử dụng cho LastModified columns..is một cái gì đó này khác nhau hoặc bạn có thể làm rõ tại sao bạn không muốn sử dụng một DateTime? – dan

+1

Tôi đọc một bài viết về lý do tại sao datatype DateTime không nên được sử dụng cho phiên bản và đồng thời lạc quan. Tôi không thể nhớ từng chi tiết, nhưng nó có ý nghĩa vào thời điểm đó. Tôi tin rằng đó là vì độ chính xác của kiểu dữ liệu, các bản cập nhật về mặt lý thuyết có thể xảy ra ở cùng một trường hợp chính xác gây ra các điều kiện chủng tộc. –

+0

Chỉ khi ngày/giờ không được cung cấp bởi cơ sở dữ liệu - SQL Server DATETIMEs là các phần của giây: http://msdn.microsoft.com/en-us/library/ms187819.aspx –

Trả lời

9

Tôi không muốn sử dụng số nguyên, vì tôi không muốn phải đọc giá trị để tăng giá trị đó.

UPDATE Table SET 
    IntColumn = IntColumn + 1 

Trong khi mà về mặt kỹ thuật đòi hỏi phải có đọc, tôi không thấy bất kỳ vấn đề với nó.

Bạn có thể luôn luôn chỉ cần cập nhật với giá trị như nhau:

UPDATE Table SET 
    SomeColumn = SomeColumn 

mà sẽ kích hoạt cập nhật rowversion là tốt.

ADDITION: Bạn có thể làm một cái nhìn với rowversion max của trẻ em:

SELECT Parent.*, MaxChildRowVersion as ChildVersion 
FROM Parent 
JOIN (
    SELECT ParentId, MAX(RowVersion) as MaxChildRowVersion 
    FROM Child 
    GROUP BY ParentId 
) as Child ON 
    Parent.ParentId = Child.ParentId 

Nhưng, không, bạn có thể không trực tiếp cập nhật một cột rowversion (mặc dù bạn có thể thực hiện riêng bạn có thể cập nhật với @@ DBTS, binary (8) và INSTEAD OF triggers ...)

Bạn có thể đưa ra ví dụ về điểm cuối cùng của bạn không? Nghe có vẻ đầy hứa hẹn.

Không, thực sự là không. ;) Quá nhiều công việc khi bạn chỉ có thể cập nhật lên cùng một giá trị thay vì hoặc sử dụng chế độ xem. Đó là 2 lựa chọn đơn giản nhất.

Tuy nhiên, để hoàn thành, cột nhị phân (8) với mặc định @@ DBTS (trả về số phiên bản cơ sở dữ liệu) và kích hoạt CẬP NHẬT SAU cũng cập nhật cột nhị phân sang @@ DBTS mới sẽ cung cấp cho bạn một loại psuedo-rowversion mà bạn có thể cập nhật thủ công. Nó sẽ không nhanh hơn hoặc tốt hơn là chỉ cập nhật một số cột khác với cùng giá trị.

+0

Bạn có thể đưa ra ví dụ về điểm cuối cùng của bạn không? Nghe có vẻ đầy hứa hẹn. –

1

Bạn đã xem xét sử dụng triggers? Nó có vẻ phù hợp hơn với những gì bạn đang theo đuổi.

Tôi đã làm việc trên một ứng dụng có dấu thời gian trên bảng một lần; chính xác những gì chúng tôi phải làm với họ được chứng minh là loại khó nắm bắt vì vậy chúng tôi đã kiểm tra chúng ra khỏi lược đồ. Bạn có thể đọc dấu thời gian vào các đối tượng bạn tạo dựa trên dữ liệu và kiểm tra xem liệu nó có thay đổi khi bạn cập nhật và quay lại nếu bạn thấy dữ liệu bị bẩn, nhưng đó là rất nhiều bản mẫu cho không nhiều lợi ích (tại ít nhất trong miền tôi đang làm việc).

+0

Tôi thực sự có. Nhưng tôi vẫn cần phải làm một cái gì đó trong kích hoạt của tôi để có được một cột dấu thời gian để cập nhật. Đó là câu hỏi của tôi. –

0

Những gì tôi sẽ làm, cho đến khi có ý tưởng tốt hơn, là thêm cột DateTime vào bảng cha của tôi có tên DateChildrenChanged.

Tôi sẽ thêm trình kích hoạt trên bảng con sẽ đặt cột DateChildrenChanged thành DateTime hiện tại và khi điều đó xảy ra, cột dấu thời gian trên bảng cha cũng sẽ được cập nhật.

Bằng cách này tôi đang sử dụng cột dấu thời gian cho phiên bản.

Tôi vẫn rất cởi mở với ý tưởng.

+0

Tôi nghĩ đó là cách tốt nhất để đi. Giữ TIMESTAMP/ROWVERSION của bạn để phiên bản của hàng thực tế. Nếu bạn cần phiên bản các hàng con của bạn - có cột TIMESTAMP/ROWVERSION ở đó, quá –

4

Ronnie,

Đầu tiên của tất cả các cú pháp timestamp đang bị phản đối bởi Microsoft, vì vậy bạn cần phải sử dụng rowversion, thứ hai rowversion luôn liên quan đến hàng.

Từ các tài liệu:

rowversion

Mỗi cơ sở dữ liệu có được một bộ đếm được tăng lên cho mỗi chèn hoặc cập nhật hoạt động được thực hiện trên một bảng có chứa một rowversion cột trong cơ sở dữ liệu. Bộ đếm này là cơ sở dữ liệu rowversion.

Tuy nhiên, vì cách nó được triển khai trong máy chủ SQL, bạn cần sử dụng trình kích hoạt để đạt được những gì bạn muốn.

Something như thế này:

CREATE TRIGGER tgUpdateParentRowVersion ON ChildTable FOR INSERT, DELETE, UPDATE 
AS 
BEGIN 
    /* 
    * The updates below force the update of the parent table rowversion 
    */ 
    UPDATE ParentTable 
     SET ChildUpdate = ChildUpdate + 1 
    FROM ParentTable a 
    JOIN inserted i on a.pkParentTable = i.fkParentTable 

    UPDATE ParentTable 
     SET ChildUpdate = ChildUpdate - 1 
    FROM ParentTable a 
    JOIN deleted  d on a.pkParentTable = d.fkParentTable 
END 
+0

Về việc không dùng nữa, mặc dù đó là một cách khác xung quanh: hàng tuần không được chấp nhận. Tôi có thể sai ... –

+0

@Ronnie: bạn ** là sai và Paulo là đúng. TIMESTAMP không được chấp nhận vì tên của nó gây ra rất nhiều sự nhầm lẫn (mọi người nghĩ rằng có một cách để chuyển đổi trở lại thành ngày và giờ). ROWVERSION là cách mới để đi –

+0

Tôi đã chỉnh sửa. Cảm ơn. –

Các vấn đề liên quan