복붙노트

[SQL] 삽입, 업데이트 SQL Server에서 proc 디렉토리에 저장

SQL

삽입, 업데이트 SQL Server에서 proc 디렉토리에 저장

나는 그렇지 않으면 삽입을 할 것, 기록이있는 경우 업데이 트를 할 것입니다 저장된 프로 시저를 작성했습니다. 그것은 다음과 같은 :

update myTable set Col1=@col1, Col2=@col2 where ID=@ID
if @@rowcount = 0
insert into myTable (Col1, Col2) values (@col1, @col2)

이 방법을 쓰고 뒤에 내 논리는 업데이트가 0을 반환 한 후 삽입이 일어날 경우 암시가 어디에 절을 사용하여 선택하고 수행 할 것입니다.

이런 식으로 일에 대한 대안을 선택하고 행의 수에 따라 어느 반환 된이 업데이트 나 삽입을 할 것입니다. 당신이 업데이 트를 할 경우는 2 개 선택 (첫 번째 명시 적으로 선택 호출과 위치 업데이트의 두 번째 암시)를 발생할 수 있기 때문에 나는 비효율적으로 간주. proc 디렉토리가 삽입 작업을 수행하는 경우 효율성에 차이가 없을 것입니다.

내 논리 소리가 여기인가? 이 저장 프로 시저에 삽입 및 업데이트를 결합 얼마나 있습니까?

해결법

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

    1.귀하의 가정이 할 수있는 최적의 방법과는 upsert / 병합이라고, 권리입니다.

    귀하의 가정이 할 수있는 최적의 방법과는 upsert / 병합이라고, 권리입니다.

    UPSERT의 중요성 - sqlservercentral.com에서 :

    편집하다: 이 답변이 패턴 어떻게 안전하게 작동하게하는 방법의 문제에 대해 배울 수있는 링크 된 블로그 게시물을 확인하시기 바랍니다.

  2. ==============================

    2.좋은 내 블로그에 게시물을 읽어 보시기 바랍니다, 안전 패턴 당신은 사용할 수 있습니다. 이 고려 사항이 많이 있으며,이 질문에 대한 허용 대답은 안전 거리가 멀다.

    좋은 내 블로그에 게시물을 읽어 보시기 바랍니다, 안전 패턴 당신은 사용할 수 있습니다. 이 고려 사항이 많이 있으며,이 질문에 대한 허용 대답은 안전 거리가 멀다.

    신속한 답변을 위해 다음과 같은 패턴을 시도해보십시오. 그것은 2000 위의 SQL에서 잘 작동합니다. SQL 2005는 당신에게 다른 옵션을 열어 오류 처리를 제공하고 SQL 2008 년 당신에게 MERGE 명령을 제공합니다.

    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
    
  3. ==============================

    3.SQL Server와 함께 사용하는 경우 2000/2005 원래의 코드는 데이터가 동시 시나리오에서 일관성을 유지하는지 확인하기 위해 거래로 묶어야합니다.

    SQL Server와 함께 사용하는 경우 2000/2005 원래의 코드는 데이터가 동시 시나리오에서 일관성을 유지하는지 확인하기 위해 거래로 묶어야합니다.

    BEGIN TRANSACTION Upsert
    update myTable set Col1=@col1, Col2=@col2 where ID=@ID
    if @@rowcount = 0
    insert into myTable (Col1, Col2) values (@col1, @col2)
    COMMIT TRANSACTION Upsert
    

    이는 추가적인 성능 비용이 발생하지만, 데이터 무결성을 보장합니다.

    이미 제안, MERGE이 가능한 경우 사용되어야한다, 추가합니다.

  4. ==============================

    4.MERGE는 방법으로, SQL Server 2008의 새로운 기능 중 하나입니다.

    MERGE는 방법으로, SQL Server 2008의 새로운 기능 중 하나입니다.

  5. ==============================

    5.당신은 또한 높은 격리 수준을 필요로 트랜잭션을 실행할 필요가 없습니다. 나는 사실 기본 격리 수준은 읽기 최선을 다하고,이 코드가 필요 직렬화이다.

    당신은 또한 높은 격리 수준을 필요로 트랜잭션을 실행할 필요가 없습니다. 나는 사실 기본 격리 수준은 읽기 최선을 다하고,이 코드가 필요 직렬화이다.

    SET transaction isolation level SERIALIZABLE
    BEGIN TRANSACTION Upsert
    UPDATE myTable set Col1=@col1, Col2=@col2 where ID=@ID
    if @@rowcount = 0
      begin
        INSERT into myTable (ID, Col1, Col2) values (@ID @col1, @col2)
      end
    COMMIT TRANSACTION Upsert
    

    어쩌면 또한 @@ 오류 확인 및 롤백을 추가하는 것은 좋은 생각이 될 수 있습니다.

  6. ==============================

    6.당신은 SQL 2008에서 병합을 시도하지 않았다면 당신은 그것을하기 위해 변경해야합니다 :

    당신은 SQL 2008에서 병합을 시도하지 않았다면 당신은 그것을하기 위해 변경해야합니다 :

    만약 @@ 행 개수 = 0, = 0 오류 @@

    업데이트가 어떤 이유로 실패, 그렇지 않은 경우 실패 문에 행 개수가 0 이후 때문에 다음 시도하고 삽입하는 것

  7. ==============================

    7.UPSERT의 큰 팬은 정말 관리 할 수있는 코드를 아래로 잘라냅니다. ID가 NULL 또는 0, 당신은이 INSERT 알고있는 경우 입력 매개 변수 중 하나는, ID입니다 그렇지 않으면 업데이 트입니다 : 여기에 내가 그것을 할 또 다른 방법입니다. 응용 프로그램이 모든 상황에서 작동 실 거예요, 그래서 ID가있을 경우 알고 있지만, 당신이 할 경우 반으로 실행하는 잘라 것입니다 가정합니다.

    UPSERT의 큰 팬은 정말 관리 할 수있는 코드를 아래로 잘라냅니다. ID가 NULL 또는 0, 당신은이 INSERT 알고있는 경우 입력 매개 변수 중 하나는, ID입니다 그렇지 않으면 업데이 트입니다 : 여기에 내가 그것을 할 또 다른 방법입니다. 응용 프로그램이 모든 상황에서 작동 실 거예요, 그래서 ID가있을 경우 알고 있지만, 당신이 할 경우 반으로 실행하는 잘라 것입니다 가정합니다.

  8. ==============================

    8.당신의 논리는 소리를 보이지만, 당신은 당신이 특정 기본 키에 통과 한 경우 삽입을 방지하기 위해 몇 가지 코드를 추가하는 것을 고려 할 수 있습니다.

    당신의 논리는 소리를 보이지만, 당신은 당신이 특정 기본 키에 통과 한 경우 삽입을 방지하기 위해 몇 가지 코드를 추가하는 것을 고려 할 수 있습니다.

    업데이트가 모든 레코드에 영향을주지 않은 경우 당신은 항상 삽입을하고 있다면 누군가가 "UPSERT"실행하기 전에 레코드를 삭제하는 경우 그렇지 않으면 어떻게됩니까? 대신 기록을 만들 것이다, 그래서 이제 업데이트하려고했던 기록은 존재하지 않습니다. 그건 아마 당신이 찾고 있던 동작하지 않습니다.

  9. ==============================

    9.수정 디마 Malenko 포스트 :

    수정 디마 Malenko 포스트 :

    SET TRANSACTION ISOLATION LEVEL SERIALIZABLE 
    
    BEGIN TRANSACTION UPSERT 
    
    UPDATE MYTABLE 
    SET    COL1 = @col1, 
           COL2 = @col2 
    WHERE  ID = @ID 
    
    IF @@rowcount = 0 
      BEGIN 
          INSERT INTO MYTABLE 
                      (ID, 
                       COL1, 
                       COL2) 
          VALUES      (@ID, 
                       @col1, 
                       @col2) 
      END 
    
    IF @@Error > 0 
      BEGIN 
          INSERT INTO MYERRORTABLE 
                      (ID, 
                       COL1, 
                       COL2) 
          VALUES      (@ID, 
                       @col1, 
                       @col2) 
      END 
    
    COMMIT TRANSACTION UPSERT 
    

    당신은 트랩 오류를 할 수 있고 실패 삽입 테이블에 레코드를 보낼 수 있습니다. 나는 우리가 WSDL을 통해 전송되는 어떤 데이터를 가지고 있기 때문에이 작업을 수행하기 위해 필요하고 가능하면 고정 내부적.

  10. from https://stackoverflow.com/questions/13540/insert-update-stored-proc-on-sql-server by cc-by-sa and MIT license