Tôi đang cố gắng tìm ra cách tốt nhất để chèn bản ghi vào một bảng duy nhất nhưng chỉ khi mục chưa tồn tại. KEY trong trường hợp này là trường NVARCHAR (400). Đối với ví dụ này, giả sử đó là tên của một từ từ trong Từ điển tiếng Anh Oxford/chèn từ điển fav của bạn tại đây. Ngoài ra, tôi đoán tôi sẽ cần phải làm cho trường Word một khóa chính. (bảng cũng sẽ có một mã định danh duy nhất PK).SQL Server - Cách chèn một bản ghi và đảm bảo rằng nó là duy nhất
Vì vậy, tôi có thể nhận được những từ này mà tôi cần thêm vào bảng ...
ví dụ:
- Cát
- Chó
- Foo
- Bar
- PewPew
- vv ...
Vì vậy, theo truyền thống, tôi sẽ thử như sau (pseudo code)
SELECT WordID FROM Words WHERE Word = @Word
IF WordID IS NULL OR WordID <= 0
INSERT INTO Words VALUES (@Word)
tức là. Nếu từ không tồn tại, sau đó chèn nó vào.
Bây giờ .. vấn đề tôi lo lắng là chúng tôi đang nhận được rất nhiều lượt truy cập .. vì vậy có thể từ đó có thể được chèn từ một quá trình khác giữa SELECT và INSERT .. sau đó ném một lỗi ràng buộc? (ví dụ: Race Condition).
sau đó tôi nghĩ rằng tôi có thể có thể làm như sau ...
INSERT INTO Words (Word)
SELECT @Word
WHERE NOT EXISTS (SELECT WordID FROM Words WHERE Word = @Word)
về cơ bản, chèn một từ khi nó không tồn tại.
Cú pháp sai sang một bên, tôi không chắc liệu điều này là xấu hay tốt vì cách nó khóa bảng (nếu có) và không phải là người biểu diễn trên một bảng mà nó nhận được đọc lớn và nhiều viết .
Vì vậy - bạn nghĩ gì về Sql?
Tôi đã hy vọng có một chèn đơn giản và 'bắt' cho bất kỳ lỗi nào được ném.
Có sự khác biệt về hiệu suất giữa EXISTS (SELECT * FROM ...) và EXISTS (SELECT 1 FROM ...) không? Tôi luôn luôn có xu hướng sử dụng sau này, để tránh các ngôi sao - là có lợi hoặc là tất cả như nhau? – Tomalak
Tôi nghi ngờ rằng tất cả đều giống nhau, nhưng bạn phải kích hoạt nó trong SQL Server Profiler để chắc chắn. –
Tôi cũng không bao giờ chọn * trong các lựa chọn của mình, nhưng luôn luôn chỉ định trường trả về/giá trị. –