我使用以下构造插入新记录(如果它不存在)。如果它存在,那么它将更新该记录。我想知道它是否是线程安全的。我的意思是两个线程尝试插入记录,这将创建重复的条目。处理此类查询的最佳方法是什么?我是否需要将这些语句放在事务块中?
UPDATE Table1 SET (...) WHERE Column1='SomeValue'
IF @@ROWCOUNT=0
INSERT INTO Table1 VALUES (...)
答案 0 :(得分:4)
如果先进行插入,会更安全一些:
insert Table1 (...columns...) select ..values... where not exists (
select * from table1 where Column1 = 'SomeValue')
if @@rowcount = 0 update Table1 set (...) where Column1 = 'SomeValue'
这样,检查存在和插入是同一声明的一部分。因此,update
和insert
之间没有空间,其他连接可以插入该行。
答案 1 :(得分:0)
这是对Andomar帖子的更详细解释。我正在向Andomar致敬,只是说明它如何更加详细并纠正了一个小错误。
DECLARE @s VARCHAR(100)
SET @s = 'somevalue'
DECLARE @t TABLE (column1 VARCHAR(100), column2 VARCHAR(18))
INSERT @t
SELECT @s, 'First example'
WHERE NOT EXISTS ( SELECT 1 FROM @t WHERE Column1 = @s)
IF @@rowcount = 0 UPDATE @t SET column2 = 'Second example' WHERE Column1 = @s
-- at first the value does not exists and is inserted
SELECT * FROM @t
-- same script again, notice how the second example is chosen because it already exists
INSERT @t
SELECT @s, 'First example'
WHERE NOT EXISTS ( SELECT 1 FROM @t WHERE Column1 = @s)
IF @@rowcount = 0 UPDATE @t SET column2 = 'Second example' WHERE Column1 = @s
-- new the line exists and column 2 is updated
SELECT * FROM @t
column1 column2
----------- -------------
somevalue First example
column1 column2
----------- --------------
somevalue Second example