복붙노트

[SQL] UPDATE 경우는 SQL Server 2008의 다른 INSERT 존재 [중복]

SQL

UPDATE 경우는 SQL Server 2008의 다른 INSERT 존재 [중복]

나는 기록이 다른 하나의 문을 사용하여 SQL Server의 새로운 기록 동작을 입력 존재하는 경우 내가 UPSERT 또는 다른 단어 UPDATE에서을 사용하는 방법을 알고 싶어?

이 예는 여기에 오라클이 달성의 방법을 보여줍니다 그러나 그것은하지 SQL 서버에 존재 않습니다 그것을위한 듀얼 테이블을 사용합니다.

그래서, 모든 SQL 서버 대안은 (없음 저장 프로 시저)하세요?

해결법

  1. ==============================

    1.많은 사람들은 MERGE를 사용하는 것이 좋습니다 것입니다,하지만 난 그것에 대하여 당신을 경고한다. 기본적으로 여러 문장보다 더 동시성 및 경쟁 조건에서 당신을 보호하지 않지만, 다른 위험을 소개 않습니다 :

    많은 사람들은 MERGE를 사용하는 것이 좋습니다 것입니다,하지만 난 그것에 대하여 당신을 경고한다. 기본적으로 여러 문장보다 더 동시성 및 경쟁 조건에서 당신을 보호하지 않지만, 다른 위험을 소개 않습니다 :

    http://www.mssqltips.com/sqlservertip/3074/use-caution-with-sql-servers-merge-statement/

    심지어이 "간단"구문을 사용할 수와 함께, 난 여전히 (오류가 간결함을 위해 생략 핸들링)이 방법을 선호한다 :

    SET TRANSACTION ISOLATION LEVEL SERIALIZABLE;
    BEGIN TRANSACTION;
    UPDATE dbo.table SET ... WHERE PK = @PK;
    IF @@ROWCOUNT = 0
    BEGIN
      INSERT dbo.table(PK, ...) SELECT @PK, ...;
    END
    COMMIT TRANSACTION;
    

    여러분의 많은이 방법을 제안합니다 :

    SET TRANSACTION ISOLATION LEVEL SERIALIZABLE;
    BEGIN TRANSACTION;
    IF EXISTS (SELECT 1 FROM dbo.table WHERE PK = @PK)
    BEGIN
      UPDATE ...
    END
    ELSE
    BEGIN
      INSERT ...
    END
    COMMIT TRANSACTION;
    

    그러나이 모든 수행은 행 (들)을 업데이트 할를 찾아 두 번 테이블을 읽어 들일 필요가 있습니다 보장된다. 첫 번째 샘플에서는 오직 한 번 행을 찾을 필요가있을 것이다. (어떤 행이 초기 읽기로부터 발견되지 않으면 두 경우, 삽입물은 발생한다.)

    다른 사람들은이 방법을 제안합니다 :

    BEGIN TRY
      INSERT ...
    END TRY
    BEGIN CATCH
      IF ERROR_NUMBER() = 2627
        UPDATE ...
    END CATCH
    

    거의 모든 삽입이 실패 드문 시나리오를 제외하고, 훨씬 더 비싼 당신이 처음에 예방할 수 있다는 SQL 서버 캐치 예외를시키는 것보다 다른 이유 그러나,이 문제가된다. 나는 많은 여기로 증명 :

    아니 당신이 이득을 하나의 문을함으로써 당신을 어떻게 생각하는지; 나는 당신이 무엇을 얻을 수 있다고 생각하지 않습니다. MERGE는 하나의 명령문하지만 여전히 정말 어쨌든 여러 작업을 수행 할 수있다 -이 있습니다 비록 당신이하지 않는 생각합니다.

  2. from https://stackoverflow.com/questions/21208719/update-if-exists-else-insert-in-sql-server-2008 by cc-by-sa and MIT license