2011-07-04 2 views
1

가능한 중복 삽입 : 내가 사용하고
Atomic UPSERT in SQL Server 2005T-SQL 업데이트는 다른 좋은 방법을

는 IT가 존재하지 않는 경우 새 레코드를 삽입하는 구성 다음과 같습니다. 존재하면 해당 레코드를 갱신합니다. 그것은 스레드 안전면 궁금하네요. 두 개의 스레드가 중복 된 항목을 생성하는 레코드를 삽입하려고합니다. 이러한 유형의 쿼리를 처리하는 가장 좋은 방법은 무엇입니까? 이 문장을 트랜잭션 블록에 넣어야합니까? 먼저 삽입 할 경우

UPDATE Table1 SET (...) WHERE Column1='SomeValue' 

IF @@ROWCOUNT=0 
    INSERT INTO Table1 VALUES (...) 

답변

0

이것은 Andomar의 게시물에 대한 자세한 설명입니다. 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 
+0

설명 주셔서 감사합니다. – kumar

4

그것은 조금 더 안전 :

insert Table1 (...columns...) select ..values... where not exists (
    select * from table1 where Column1 = 'SomeValue') 

if @@rowcount = 0 update Table1 set (...) where Column1 = 'SomeValue' 

그 방법을, 실존 및 삽입에 대한 검사는 같은 성명의 일부입니다. 따라서 다른 연결에서 행을 삽입 할 수있는 updateinsert 사이에는 여유 공간이 없습니다.

+0

삽입 구문이 잘못되었습니다. SQL Server는 그것을 좋아하지 않습니다. 직렬화 가능 잠금을 사용할 수 있다고 생각합니다. – kumar

+0

@Andomar :'WHERE'는 본질적으로'INSERT'의 일부가 아니므로'INSERT ... VALUES'와 함께 사용할 수 없습니다. 그러나 * SELECT *의 일부가 될 수 있습니다. 즉, INSERT ... SELECT와 함께 WHERE를 사용할 수 있습니다. –

+0

@kumar, Andriy 남 : 네가 맞아, 대답으로 편집 됨 – Andomar