DBMS: MS SQL Server 2005, Standardchế độc đáo trong một nhóm các hồ sơ, nơi một số giá trị là như nhau
Tôi muốn làm một hạn chế bảng để chỉ có một kỷ lục có một giá trị đặc biệt trong vòng một tập hợp con của bảng (trong đó các hàng chia sẻ một giá trị trong một cột cụ thể). Điều này có thể không?
Ví dụ: Tôi có hồ sơ trong myTable trong đó có một chính nước ngoài không duy nhất (fk1), và một cột chút gọi là isPrimary để đánh dấu ra rằng một đặc biệt này nên được sử dụng bởi ứng dụng của chúng tôi cho logic đặc biệt.
trong trừu tượng, nó trông như thế này:
myTable
-------------
pk1 (int, not null)
name (varchar(50), null)
fk1 (int, not null)
isPrimary (bit, not null)
tôi muốn đảm bảo rằng có một và chỉ một kỷ lục với cờ isPrimary thiết lập để 1, đối với mỗi giá trị duy nhất của fk1.
dữ liệu Ví dụ: này cần được pháp luật:
pk1 name fk1 isPrimary
---- ----- ----- ----------
1 Bill 111 1
2 Tom 111 0
3 Dick 222 1
4 Harry 222 0
Nhưng điều này nên không được (nhiều hơn một nơi fk = 111):
pk1 name fk1 isPrimary
---- ----- ----- ----------
1 Bill 111 1
2 Tom 111 1
3 Dick 222 1
4 Harry 222 0
Và không nên này (none trong đó fk = 222):
pk1 name fk1 isPrimary
---- ----- ----- ----------
1 Bill 111 1
2 Tom 111 0
3 Dick 222 0
4 Harry 222 0
có cách nào để làm điều này với một ràng buộc bảng?
CẬP NHẬT tôi đã đi với câu trả lời Martin Smith cho bây giờ, mặc dù tôi sẽ được thúc đẩy cấu trúc lại JohnFx trong một bản phát hành sắp tới, vì nó là giải pháp lâu dài tốt nhất. Tuy nhiên tôi muốn đăng UDF cập nhật của tôi dựa trên câu trả lời của Raze2dust, trong trường hợp người đọc trong tương lai quyết định rằng nó phù hợp hơn với nhu cầu của họ.
CREATE FUNCTION [dbo].[OneIsPrimaryPerFK1](@fk1 INT, @dummyIsPrimary BIT)
RETURNS INT
AS
BEGIN
DECLARE @retval INT;
DECLARE @primarySum INT;
SET @retval = 0;
DECLARE @TempTable TABLE (
fk1 INT,
PrimarySum INT)
INSERT INTO @TempTable
SELECT fk1, SUM(CAST(isPrimary AS INT)) AS PrimarySum
FROM FacAdmin
WHERE fk1 = @fk1
GROUP BY fk1;
SELECT @primarySum = PrimarySum FROM @TempTable;
IF(@primarySum=1)
BEGIN
SET @retval = 1
END
RETURN @retval
END;
Thay đổi:
- Dùng @tempTable hơn
temptable theo yêu cầu của udf
- qua @ fk1 như một tham số vì vậy tôi có thể (trong bộ nhớ v ghi vào đĩa.) chọn cho tính duy nhất trong một nhóm giá trị fk1.
- khó khăn cũng đã vượt qua isPrimary mặc dù nó không phải là cần thiết cho logic của chức năng, nếu không SQL2005 ưu sẽ không chạy ràng buộc kiểm tra khi isPrimary là cập nhật.
Mặc dù giải pháp của JohnFx là giải pháp lâu dài tốt nhất, đây là giải pháp cho tôi ngay bây giờ. –