2011-08-31 71 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,但只能根据满足哪些条件使用其中一个语句触摸表。