developer tip

SQL Server 2005의 MySQL REPLACE INTO 구현?

copycodes 2020. 9. 22. 08:22
반응형

SQL Server 2005의 MySQL REPLACE INTO 구현?


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

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

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

SQL Server 2005에 이러한 기능을 구현 하는 쉽고 보편적 인 방법 이 있는지 궁금합니다 .


이것은 MSSQL에 대해 나를 짜증나게하는 것입니다 ( 내 블로그에서 폭언 ). MSSQL이 지원되기를 바랍니다 upsert.

@ Dillie-O의 코드는 이전 SQL 버전 (+1 투표)에서 좋은 방법이지만 여전히 기본적으로 두 개의 IO 작업입니다 ( exists다음에 updateor 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라고합니다. 이름이 무엇인지 아는 것이 원하는 것을 찾는 데 도움이 될 수 있습니다.

I don't think SQL Server 2005 has any great ways of doing this. 2008 introduces the MERGE statement that can be used to accomplish this as shown in: http://www.databasejournal.com/features/mssql/article.php/3739131 or http://blogs.conchango.com/davidportas/archive/2007/11/14/SQL-Server-2008-MERGE.aspx

Merge was available in the beta of 2005, but they removed it out in the final release.


What the upsert/merge is doing is something to the effect of...

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

So hopefully the combination of those articles and this pseudo code can get things moving.


I wrote a blog post about this issue.

The bottom line is that if you want cheap updates ... and you want to be safe for concurrent usage. try:

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

This way you have 1 operation for updates and a max of 3 operations for inserts. so, if you are generally updating this is a safe cheap option.

I would also be very careful not to use anything that is unsafe for concurrent usage. Its really easy to get primary key violations or duplicate rows in production.

참고URL : https://stackoverflow.com/questions/234/sql-server-2005-implementation-of-mysql-replace-into

반응형