2012-02-26 36 views
7

Được rồi, vậy câu hỏi SQL nhanh ở đây (sử dụng sql-server-2008).SQL Chọn hoặc Chèn ID trả lại

Tôi có một bảng vẽ bản đồ names với các cột sau

IDDisplayName

Những gì tôi muốn làm là đầu tiên SELECT [ID] FROM [names] WHERE [DisplayName] = 'chuck';

NHƯNG, nếu tên 'chuck' không tồn tại trong cơ sở dữ liệu, tôi muốn tạo nó và trả về tự động tăng lên ID.

Tôi đã tự hỏi liệu SQL có xây dựng một số cách để làm điều này một cách dễ dàng, hoặc nếu tôi phải đi theo con đường dài?

tuyến đường dài là một cái gì đó như thế này

SELECT COUNT(ID) AS count, ID FROM names WHERE DisplayName='chuck' 
IF(count > 0) 
    SELECT ID as ReturnID; 
ELSE 
    BEGIN 
    INSERT INTO names(DisplayName) values('chuck'); 
    SELECT scope_identity() as ReturnID; 
    END 

tôi đã không kiểm tra rằng tuyên bố cuối cùng, nhưng tôi giả định các chặng đường dài sẽ là một cái gì đó như thế. Nếu không có được xây dựng trong cách, tôi sẽ đánh giá cao nếu ai đó chỉ đơn giản là có thể chính xác tuyên bố đó (như tôi chắc chắn nó không phải là hoàn toàn chính xác).

+3

Nếu chỉ hỗ trợ 200 * +, hãy sử dụng [Cú pháp MERGE] (http://technet.microsoft.com/en-us/library/bb510625.aspx) –

+0

Bạn có thể cung cấp ví dụ không? Tôi đang cố gắng tìm hiểu các cách nâng cao hơn khi sử dụng sql. –

+0

@ kelton52: có ví dụ ở cuối bài báo OMG Ponies được liên kết. Bạn cần cuộn xuống một chút. –

Trả lời

4

Bạn nên chăm sóc về các giao dịch cũng như:

set XACT_ABORT on 
begin tran 

declare @ID int 

select @ID = ID from names with (holdlock, updlock) WHERE DisplayName='chuck' 

if @@rowcount = 0 
begin 
    INSERT INTO names(DisplayName) values('chuck'); 
    set @ID = scope_identity(); 
end 

select @ID as ReturnID; 

commit tran 

Lưu ý việc sử dụng gợi ý bảng - HOLDLOCKupdlock. Chúng ngăn chặn một chuỗi khác thực hiện chính xác cùng một truy vấn và tạo hàng lần thứ hai. Để biết thêm thông tin tìm cách ly, đồng bộ hóa, deadlocks, cập nhật đồng thời.

+0

Được rồi, vậy hãy chạy cái này và bây giờ các bảng bị bế tắc ... bất kỳ ý tưởng nào? –

+0

bạn cũng có từ trong đó hai lần, giả sử rằng không cố ý –

+0

cũng sql không nhận ra xac_abort –

0

tôi sẽ làm:

IF (NOT EXISTS(SELECT null from names where DisplayName='Chuck')) 
    INSERT INTO Names (DisplayName) Values ('Chuck') 

SELECT ID as ReturnID FROM Names where DisplayName='Chuck' 

Không tiết kiệm nhiều mặc dù

+0

Đây không phải là lúc thực hiện tốt nhất 2 truy vấn và điều tồi tệ nhất là thực hiện 1 truy vấn? – crush

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