2012-12-20 3 views
0

파티션 테이블과 업데이트 함수/트리거가 있습니다. 행이 업데이트되면 먼저 행을 삭제 한 다음 적절한 행에 삽입합니다. 내 질문은 Oracle에서 MERGE와 유사한 명령문을 작성하려고하는 것입니다. - 삭제 및 특정 행에 삽입 한 후 삽입이 원인파티션 테이블의 Postgres에있는 UPSERT 문

WITH upsert as 
(
    update mytable2 m 
     set sales=m.sales+d.sales, 
      status=d.status 
    from mytable d 
    where m.pid=d.pid 
    RETURNING m.* 
) 
insert into mytable2 
select a.pid, a.sales, 'NEW' 
from mytable a 
where a.pid not in (select b.pid from upsert b); 

그러나, 문제는 업데이트가 첫번째 발사이다 : I는 다음과 같은 UPSERT를 사용하여 포스트 그레스에서 비슷한 구현에 대한 참조를 발견 다시 삽입하십시오. 파티션에 대한 업데이트 기능/트리거 때문입니다. 중복을 일으키지 않거나 제약 조건 위반에 실패하지 않고 병합 (예 : 행을 찾았거나, 업데이트하거나, 삽입하는 경우)과 같이 Oracle에서 수행하는 것과 같은 방식으로 작동합니까?

귀하의 도움에 감사드립니다.

+0

게시 한 upsert 코드와 아무 관련이없는 업데이트 기능/트리거가 있습니까? –

+0

업데이트 트리거 위에 위의 예제를 사용하면 mytable2 분할 테이블에있게됩니다. 트리거는 각 파티션에 있으며 업데이트 전에 실행됩니다. OLD.pid = pid 인 행을 삭제합니다 (위의 예와 같이). 그런 다음 NEW. * 값을 사용하여 삽입합니다. 이 함수/트리거는 큰 테이블이므로 테이블을 관리하는 데 필요합니다. 내가 분석 데이터베이스이고 매일 새로운 행을 얻고 싶기 때문에 내가하고 싶은 다른 프로세스는 테이블에 매일 병합됩니다. 더 이상의 질문이 있으면 알려주세요. 귀하의 답변에 감사드립니다. – user3412041

+0

죄송합니다, 트리거가 표시되지 않습니다. 분할 된 테이블이 보이지 않습니다. INprotible EXISTS 구조로 IN을 대체 할 것입니다. – wildplasser

답변

0

여기에서 문제는 null을 리턴하는 트리거와 리턴 된 결과를 예상하는 upserts의 교집합에 있습니다. 본질적으로 무슨 일을하는 것입니다 :

  1. 삭제 행
  2. 삽입 행
  3. 중단 업데이트는 업데이트가 완료되었는지
  4. 체크 (이것은 당신의 upsert와 함께 놨 무엇을) 삽입되지 않은 경우.

트리거가 소프트웨어 흐름을 중단시키기 때문에 몇 가지 문제가 발생할 수 있습니다.

그래서 만드는 방법이 작업 .....

나는 상당히 큰 집합에이 일을하는 쉬운 방법을 볼 수 없습니다. 업데이트 부분을 호출 할 수있는 함수로 옮겨야한다고 생각합니다. 이 함수의 특성은 한 번에 실제로 얼마나 많은 행을 업데이트하는지에 달려 있습니다. 그런 다음 CTE 대신 함수 호출을 사용하여 수행중인 것과 비슷한 INSERT ... SELECT을 수행 할 수 있습니다.