[mysql] SQL Server 2005의 MySQL REPLACE INTO 구현?

MySQL에는 매우 유용하면서도 독점적 인 REPLACE INTOSQL 명령이 있습니다.

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

새 트랜잭션을 시작하고 a를 수행 한 Select()다음 UPDATE또는 INSERTCOMMIT 수행하는 것은 특히 응용 프로그램에서 수행하고 따라서 항상 두 가지 버전의 문을 유지할 때 약간의 고통입니다.

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', ... )

이렇게하면 업데이트 인 경우 하나의 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 년에는 http://www.databasejournal.com/features/mssql/article.php/3739131 또는 http://blogs.conchango.com/davidportas/archive/ 와 같이이를 수행하는 데 사용할 수있는 MERGE 문이 도입되었습니다. 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 개입니다. 따라서 일반적으로 업데이트하는 경우 안전하고 저렴한 옵션입니다.

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


답변