2011-08-31 75 views
2

我有一個過程,我不想跟蹤是否有創建或更新。跟蹤將是複雜的。我想執行創建或更新。該模式是像...如何在T-SQL中編寫簡單的插入或更新?

col1 varchar() (PK) 
col2 varchar() (PK) 
col3 varchar() (PK) 
col4 varchar() 

我想這樣做

TRY 
{ 
    INSERT ... 
} 
CATCH(DuplicateKeyException) 
{ 
    UPDATE ... 
} 

你有什麼建議?


我想確保我瞭解其他頂級投票答案。根據我的模式,UPDATE總是會發生(即使是使用INSERT),但插入只發生在不存在的地方?

//UPSERT 
INSERT INTO [table] 
SELECT [col1] = @col1, [col2] = @col2, [col3] = @col3, [col4] = @col4 
FROM [table] 
WHERE NOT EXISTS (
    -- race condition risk here? 
    SELECT 1 
    FROM [table] 
    WHERE [col1] = @col1 
     AND [col2] = @col2 
     AND [col3] = @col3 
) 

UPDATE [table] 
SET [col4] = @col4 
WHERE [col1] = @col1 
    AND [col2] = @col2 
    AND [col3] = @col3 
+3

您使用的是什麼RDBMS(包括版本)? –

+2

AKA [upsert](http://en.wikipedia.org/wiki/Upsert)。 – Oded

+0

對不起,SQL 2000.更新後。 –

回答

6
update table1 set col1=1,col2=2,col3=3 where a=1 
if @@ROWCOUNT=0 
    insert into table1 (col1,col2,col3) values (1,2,3) 

我認爲它比首先檢查存在更快。

+0

+1 - 不要使用@Martin的鏈接說這是一個DUP。那裏的UPSERT代碼會導致非常難以查明的間歇性錯誤。如果你想使用該方法,然後看到我的答案在這裏http://stackoverflow.com/questions/7263445/sql-c-primary-key-error-on-upsert –

+0

@ P.Brian.Mackey我得到不同的印象您沒有正確閱讀該答案,只是盲目地複製了代碼。文字解釋了爲什麼它不起作用並給出了替代方案。 –

+0

@Martin - 我不是SQL專家,但我不同意他的邏輯。我不明白爲什麼當你需要做的是脫離FROM時爲什麼需要瀏覽一個值得「原子操作」細節的頁面。對我來說,這個答案就是過度工程的定義。 –

0

可以使用MERGE聲明(如果你使用T-SQL)或創建一個查詢,做基於密鑰的存在INSERT或UPDATE。編輯:OP已編輯他的問題。是的,每次執行此查詢時,您都會在技術上運行UPDATE和INSERT,但只能根據滿足哪些條件使用其中一個語句觸摸表。