문제

MySQL에는 매우 유용하면서도 고유한 기능이 있습니다. REPLACE INTO SQL 명령.

SQL Server 2005에서 이를 쉽게 에뮬레이트할 수 있습니까?

새로운 거래 시작하기 Select() 그리고 다음 중 하나 UPDATE 또는 INSERT 그리고 COMMIT 항상 약간의 고통이 따릅니다. 특히 애플리케이션에서 이를 수행할 때 항상 두 가지 버전의 명령문을 유지합니다.

쉽고 간편한 방법이 있는지 궁금합니다. 만능인 SQL Server 2005에 이러한 기능을 구현하는 방법은 무엇입니까?

도움이 되었습니까?

해결책

이것은 MSSQL에 대해 나를 짜증나게 하는 것입니다(내 블로그에 욕해).MSSQL이 지원됐으면 좋겠어요 upsert.

@Dillie-O의 코드는 이전 SQL 버전(+1 투표)에서 좋은 방법이지만 여전히 기본적으로 두 개의 IO 작업입니다( exists 그리고 나서 update 또는 insert)

조금 더 좋은 방법이 있어요 이 게시물, 기본적으로:

--try an update
update tablename 
set field1 = 'new value',
    field2 = 'different value',
    ...
where idfield = 7

--insert if failed
if @@rowcount = 0 and @@error = 0
    insert into tablename 
           ( idfield, field1, field2, ... )
    values ( 7, 'value one', 'another value', ... )

이렇게 하면 업데이트인 경우 1개의 IO 작업으로, 삽입인 경우 2개의 IO 작업으로 줄어듭니다.

MS SQL2008 소개 merge SQL:2003 표준에서:

merge tablename as target
using (values ('new value', 'different value'))
    as source (field1, field2)
    on target.idfield = 7
when matched then
    update
    set field1 = source.field1,
        field2 = source.field2,
        ...
when not matched then
    insert ( idfield, field1, field2, ... )
    values ( 7,  source.field1, source.field2, ... )

이제는 실제로 단 하나의 IO 작업이지만 끔찍한 코드입니다. :-(

다른 팁

찾고 있는 기능을 전통적으로 UPSERT라고 합니다.적어도 그것이 무엇인지 아는 것은 당신이 찾고 있는 것을 찾는 데 도움이 될 수 있습니다.

SQL Server 2005에는 이 작업을 수행할 수 있는 좋은 방법이 없다고 생각합니다.2008에는 다음과 같이 이를 수행하는 데 사용할 수 있는 MERGE 문이 도입되었습니다. http://www.databasejournal.com/features/mssql/article.php/3739131 또는 http://blogs.conchango.com/davidportas/archive/2007/11/14/SQL-Server-2008-MERGE.aspx

Merge는 2005년 베타 버전에서 사용할 수 있었지만 최종 릴리스에서는 제거되었습니다.

upsert/merge가 수행하는 작업은 다음과 같은 효과가 있습니다.

IF EXISTS (SELECT * FROM [Table] WHERE Id = X)
   UPDATE [Table] SET...
ELSE
   INSERT INTO [Table]

따라서 해당 기사와 이 유사 코드를 결합하여 작업을 진행할 수 있기를 바랍니다.

나는 썼다 이 문제에 대한 블로그 게시물.

결론은 저렴한 업데이트를 원한다면 ...동시 사용에 안전하기를 원합니다.노력하다:

update t
set hitCount = hitCount + 1
where pk = @id

if @@rowcount < 1 
begin 
   begin tran
      update t with (serializable)
      set hitCount = hitCount + 1
      where pk = @id
      if @@rowcount = 0
      begin
         insert t (pk, hitCount)
         values (@id,1)
      end
   commit tran
end

이렇게 하면 업데이트에 대해 1개의 작업이 있고 삽입에 대해 최대 3개의 작업이 가능합니다.따라서 일반적으로 업데이트하는 경우 이는 안전하고 저렴한 옵션입니다.

또한 동시 사용에 안전하지 않은 것을 사용하지 않도록 매우 주의할 것입니다.프로덕션에서 기본 키 위반이나 중복 행을 얻는 것은 정말 쉽습니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top