Khi bạn đã xóa (các) bản sao của mình:
ALTER TABLE dbo.yourtablename
ADD CONSTRAINT uq_yourtablename UNIQUE(column1, column2);
hoặc
CREATE UNIQUE INDEX uq_yourtablename
ON dbo.yourtablename(column1, column2);
Tất nhiên, tốt hơn hết là bạn nên kiểm tra vi phạm này trước, trước khi cho phép SQL Server cố gắng chèn hàng và trả về một ngoại lệ (ngoại lệ rất đắt).
-
Tác động hiệu suất của các kỹ thuật xử lý lỗi khác nhau
-
Kiểm tra các vi phạm ràng buộc tiềm ẩn trước khi tham gia TRY / CATCH
Nếu bạn muốn ngăn các trường hợp ngoại lệ xuất hiện trong ứng dụng mà không thực hiện thay đổi đối với ứng dụng, bạn có thể sử dụng INSTEAD OF
kích hoạt:
CREATE TRIGGER dbo.BlockDuplicatesYourTable
ON dbo.YourTable
INSTEAD OF INSERT
AS
BEGIN
SET NOCOUNT ON;
IF NOT EXISTS (SELECT 1 FROM inserted AS i
INNER JOIN dbo.YourTable AS t
ON i.column1 = t.column1
AND i.column2 = t.column2
)
BEGIN
INSERT dbo.YourTable(column1, column2, ...)
SELECT column1, column2, ... FROM inserted;
END
ELSE
BEGIN
PRINT 'Did nothing.';
END
END
GO
Nhưng nếu bạn không nói với người dùng rằng họ không thực hiện chèn, họ sẽ tự hỏi tại sao dữ liệu không có ở đó và không có ngoại lệ nào được báo cáo.
CHỈNH SỬA đây là một ví dụ thực hiện chính xác những gì bạn đang yêu cầu, thậm chí sử dụng cùng tên với câu hỏi của bạn và chứng minh điều đó. Bạn nên dùng thử trước khi giả định rằng các ý tưởng trên chỉ coi một cột này hay cột kia trái ngược với sự kết hợp ...
USE tempdb;
GO
CREATE TABLE dbo.Person
(
ID INT IDENTITY(1,1) PRIMARY KEY,
Name NVARCHAR(32),
Active BIT,
PersonNumber INT
);
GO
ALTER TABLE dbo.Person
ADD CONSTRAINT uq_Person UNIQUE(PersonNumber, Active);
GO
-- succeeds:
INSERT dbo.Person(Name, Active, PersonNumber)
VALUES(N'foo', 1, 22);
GO
-- succeeds:
INSERT dbo.Person(Name, Active, PersonNumber)
VALUES(N'foo', 0, 22);
GO
-- fails:
INSERT dbo.Person(Name, Active, PersonNumber)
VALUES(N'foo', 1, 22);
GO
Dữ liệu trong bảng sau tất cả những điều này:
ID Name Active PersonNumber
---- ------ ------ ------------
1 foo 1 22
2 foo 0 22
Thông báo lỗi trên phụ trang cuối cùng:
Msg 2627, Mức 14, Trạng thái 1, Dòng 3 Vi phạm ràng buộc KEY DUY NHẤT 'uq_Person'. Không thể chèn khóa trùng lặp vào đối tượng 'dbo.Person'. Câu lệnh đã bị chấm dứt.
Ngoài ra, gần đây tôi đã viết blog về giải pháp áp dụng một ràng buộc duy nhất cho hai cột theo một trong hai thứ tự :
- Thực thi một ràng buộc duy nhất khi đơn đặt hàng không quan trọng