2010-10-22 62 views
5

Tôi có một bảng, một cái gì đó giống nhưUNIQUE chế điều khiển bởi một cột chút

FieldsOnForms(
FieldID int (FK_Fields) 
FormID int (FK_Forms) 
isDeleted bit 
) 

Cặp (FieldID, FormID) phải là duy nhất, nhưng chỉ khi nào hàng sẽ không bị xóa (isDeleted = 0).

Có thể xác định một ràng buộc như vậy trong SQLServer 2008 không? (không sử dụng trình kích hoạt)

P.S. Thiết lập (FieldID, FormID, isDeleted) là duy nhất thêm khả năng đánh dấu một hàng là đã xóa, nhưng tôi muốn có cơ hội thiết lập n hàng (theo FieldID, FormID) thành isDeleted = 1 và chỉ có một hàng isDeleted = 0

Trả lời

12

bạn có thể có một độc đáo index, sử dụng 2008 filtered indexes tính năng SQL server, hoặc bạn có thể áp dụng một chỉ số UNIQUE chống lại một cái nhìn (index lọc nghèo của con người, hoạt động chống lại các phiên bản trước), nhưng bạn không thể có một ràng buộc UNIQUE như bạn đã mô tả.

Một ví dụ về chỉ số lọc:

CREATE UNIQUE NONCLUSTERED INDEX IX_FieldsOnForms_NonDeletedUnique ON FieldsOnForms (FieldID,FormID) WHERE isDeleted=0 
+0

+1 câu trả lời hay nhất ... – gbn

+0

Mặc dù tôi đang gặp lỗi, vì trường bit (Chuyển đổi cột thành kiểu dữ liệu của hằng số không được hỗ trợ cho chỉ mục đã lọc), điều này có vẻ là giải pháp mà tôi đã loking cho. – jaraics

+0

@jaraics - Tôi vừa tạo bảng trong câu hỏi của bạn, sau đó là chỉ mục trong câu trả lời của tôi và nó được tạo mà không có lỗi. Ngoài ra, nếu bạn đang gặp phải các kiểu dữ liệu không phù hợp, thường thì tốt hơn là CAST (hoặc CONVERT) hằng số vào kiểu cột, chứ không phải theo cách khác. Không chắc liệu điều đó có khắc phục được sự cố của bạn hay không. –

1

Không, phương tiện độc đáo thực sự độc đáo. Bạn sẽ phải di chuyển các bản ghi đã xóa của bạn sang một bảng khác hoặc thay đổi IsDeleted thành một cái gì đó có thể là duy nhất trên tất cả các bản ghi đã xóa (nói một dấu thời gian). Hoặc là giải pháp sẽ yêu cầu công việc bổ sung hoặc trong ứng dụng của bạn, trong một thủ tục được lưu trữ, hoặc trong một kích hoạt.

2

Bạn có thể thay đổi cột IsDeleted thành DeletedDate và đặt thành DATETIME với thời gian chính xác khi hàng bị xóa một cách hợp lý. Ngoài ra, bạn có thể thêm một cột DeletedDate và sau đó tạo một cột được tính toán IsDeleted dựa vào đó để bạn vẫn có sẵn cột đó nếu nó đang được sử dụng trong mã. Sau đó bạn sẽ đặt một chỉ mục duy nhất trên DeletedDate (ngoài FieldID và FormId) thay vì cột IsDeleted. Điều đó sẽ cho phép chính xác một cột NULL.

Albin đăng một giải pháp tương tự như vậy, nhưng sau đó xóa nó. Tôi không chắc tại sao, nhưng nếu anh ấy đăng lại thì anh ấy đã ở đây trước tôi. :)

+0

Điều này có vẻ là một lựa chọn tốt cho các máy chủ SQL trước đó. – jaraics

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