2011-01-04 2 views
1

기본 키가 중복 인 경우 UPDATE 대신에 간단한 INSERT 쿼리를 사용해야합니다. MySQL에서는 이것이 더 쉬워 보입니다. 오라클에서는 MERGE를 사용해야 할 것 같습니다.INSERT에서 UPDATE가 Oracle의 중복 기본 키입니까?

MERGE에서 찾을 수있는 모든 예제에는 "원본"테이블과 "대상"테이블이있었습니다. 필자의 경우 소스와 대상은 같은 테이블입니다. 내 자신의 쿼리를 작성하는 예제를 이해할 수 없었습니다.

유일한 방법이 아니면 더 좋은 해결책이 있습니까?

INSERT INTO movie_ratings 
VALUES (1, 3, 5) 

그것은 기본적으로이 그리고 기본 키 때문에 업데이트가이 같은 것, 처음 2 개 값이다 : 나는 트리거를 사용하여 생각

UPDATE movie_ratings 
SET rating = 8 
WHERE mid = 1 AND aid = 3 

자동으로 UPDATE 문을 실행할 것이라고 할 때 INSERT가 호출되었지만 기본 키가 중복 된 경우에만 호출됩니다. 이런 식으로하는 데 문제가 있습니까? 방아쇠에 대한 도움이 필요합니다. 그러나 이해하는데 어려움을 겪고 있습니다.

+0

이와 같은 예에서는 INSERT에서 열 이름의 목록 (선택 사항)을 사용하여 충분한 테이블 구조를 제공하는 것이 좋습니다. 어쩌면 MySQL에서 수행 된 작업을 보여 주면 사람들은 자신이 무엇을했는지 보게 될지도 모릅니다. 아니면 아마도 내 호기심/게으름 일 것입니다. –

+0

테이블 구조는 implict, mid (int), aid (int), rating (int)입니다. –

답변

10

MERGE는 Standard SQL에서 '적절한대로 INSERT 또는 UPDATE'문을 사용하므로 아마도 Oracle SQL에서도 마찬가지입니다.

예, 당신은에서 병합하는 '테이블'을해야하지만 거의 확실 즉시 해당 테이블을 만들 수 있습니다

MERGE INTO Movie_Ratings M 
     USING (SELECT 1 AS mid, 3 AS aid, 8 AS rating FROM dual) N 
      ON (M.mid = N.mid AND M.aid = N.aid) 
     WHEN  MATCHED THEN UPDATE SET M.rating = N.rating 
     WHEN NOT MATCHED THEN INSERT( mid, aid, rating) 
          VALUES(N.mid, N.aid, N.rating); 

(. 구문이 확인되지 않음)

+0

이것은 트릭을 만들었습니다. 멋진 새로운 것들을 항상 배웁니다 :) –

+0

@ jonathan-leffler 오라클 11.1에서 저를 위해 오류가 발생했기 때문에 'USING ... AS N'에서 'AS'를 제거하는 해답을 편집했습니다. – Stompchicken

+0

오라클은 ** 다중 테이블 * * INSERT/UPDATE 문을 사용하여 삽입/업데이트하지만 MERGE 문은 포함하지 않습니다. 미완성 된 소프트웨어에 대해 말하기 ... –

1

이를위한 전형적인 방법은 SQL %의 행 = 0이 INSERT를 수행하는 경우

  • 가 삽입을 수행하고 제 업데이트를 수행하는 UPDATE 대신
  • 을 DUP_VAL_ON_INDEX 잡을하고 수행하고있다

동일한 테이블에서 다른 작업을 수행하는 테이블에는 트리거를 쓸 수 없습니다. 오라클 오류 (테이블 변경)가 발생합니다.

+0

그 사실을 알지 못했습니다. 설명해 주셔서 감사합니다. 하지만 그것은 반드시 내 질문에 대답하지 않는 코멘트가 있어야합니다. –

+0

@ Nazgulled : MERGE에 대한 의견을 추가했습니다. (지금은 대답의 자격이 있다고 생각합니다.) – sjngm

+0

@ Nazgulled : Jonathan Leffler의 제안이 실제로 그렇게 작동 할 수 있기 때문에 MERGE-stuff를 제거했습니다. 나는 다른 해결책을 염두에두고 있었다. – sjngm

0

을 나는 T 해요 -SQL 사람이지만이 경우 트리거가 좋은 해결책이 아닙니다. 대부분의 트리거는 좋은 해결책이 아닙니다. T-SQL에서, 단순히 IF가 존재하는을 수행 할

DECLARE 
    cnt NUMBER; 
BEGIN 
    SELECT COUNT(*) 
    INTO cnt 
    FROM mytable 
    WHERE id = 12345; 

    IF(cnt = 0) 
    THEN 
    ... 
    ELSE 
    ... 
    END IF; 
END; 

그 MERGE가 나타납니다 ...하지만 오라클에, 당신은 수를 선택해야합니다 (* dbo.Table WHERE ... FROM SELECT) 이 경우에 필요한 :

MERGE INTO movie_ratings mr 
USING (
    SELECT rating, mid, aid 
    WHERE mid = 1 AND aid = 3) mri 
ON (mr.movie_ratings_id = mri.movie_ratings_id) 

WHEN MATCHED THEN 
    UPDATE SET mr.rating = 8 WHERE mr.mid = 1 AND mr.aid = 3 

WHEN NOT MATCHED THEN 
    INSERT (mr.rating, mr.mid, mr.aid) 
    VALUES (1, 3, 8) 

내가 말했듯이, 나는 T-SQL 사람이야하지만 여기에 기본 개념 자체에 대해 movie_rating 테이블을 "결합"하는 것입니다. "if exists"예제를 사용할 때 성능에 문제가 없다면, 나는 그것을 읽기 쉽도록 사용할 것입니다.