2014-01-23 3 views
0

추가 기준을 upsert 구현 : 나는 데이터베이스에 작업의 삽입 또는 업데이트 유형을하려고어떻게이 유사한 테이블이

CREATE TABLE orders(
    order_id UUID PRIMARY KEY, 
    owner_id TEXT, 
    other_data TEXT 
) 

. 레코드가 이미 주어진 ORDER_ID, 주어진 OWNER_ID 일치로 존재하는 경우 레코드가 이미 주어진 ORDER_ID에있는 경우

  1. 가, 다음,
  2. 다른 기록을 갱신 : 나는 구현하기 위해 노력하고 논리는 같다 해, 지정된 OWNER_ID는 이상적으로는 예를 들어 PostgreSQL의 문서에서 custom UPSERT example를 사용하여 저장 프로 시저로 구현하고자하는 새로운 기록

를 삽입하고 그렇지 않으면 오류

  • 을 던져 일치하지 않습니다.

    두 가지 별도의 쿼리를 수행하지 않아도 위의 사례 1과 두 번째 사례를 구분할 수 있습니다. 나는이 할 경우 다음

    UPDATE orders(other_data) WHERE order_id=order_id_param AND owner_id=owner_id_param; 
    

    을 더 주문 기록이 존재하지 않았기 때문에이 경우 내가 알 수 없습니다 일치하지 않습니다, 또는 존재 않았다하지만 OWNER_ID이 일치하지 않은 경우. 내가 업데이트하기 전에이 같은 초기 쿼리를 할 수 물론

    : 오류를

    SELECT count(1) FROM orders WHERE order_id=order_id_param AND owner_id!=owner_id_param; 
    

    및 던질 경우, 반환 카운트> 0; 하지만 가능한 경우 추가 쿼리를 피하고 싶습니다.

    저는 PostgreSQL 9.2를 사용하고 있습니다.

    나는 this similar SO question을 찾았지만 SQL Server 2008 용이었고 PostgreSQL에 간단히 적용 할 수있는 방법으로 해결하지 못했습니다.

  • +0

    트리거를 사용하십시오 ... thats 작업입니다. –

    +0

    UPDATE가 owner_id의 값을 변경하려고하면 오류가 발생하는 트리거를 정의하십시오 ... 실제로는 나쁜 생각이 아닙니다. – harmic

    답변

    0

    결국 나는 owner_id가 일치하지 않으면 테이블의 UPDATE 쿼리가 성공하지 못하게하는 트리거를 정의하여이 문제를 해결했습니다.

    그것은 죽은 간단하고 다음과 같은 :

    CREATE OR REPLACE FUNCTION order_update_check() 
    RETURNS trigger 
    AS $$ 
    BEGIN 
        IF NEW.owner_id != OLD.owner_id THEN 
         RAISE EXCEPTION 'User % cannot modify order %', NEW.owning_user, OLD.order_id; 
        END IF; 
        RETURN NEW; 
    END; 
    $$ 
    LANGUAGE plpgsql; 
    
    CREATE TRIGGER order_update_trigger BEFORE UPDATE ON orders 
        FOR EACH ROW EXECUTE PROCEDURE order_update_check(); 
    

    이 정의하는 데, 나는 다음 PG docs에 설명 된대로 거의 같은 upsert 절차를 정의했다.

    @ 노란에게 감사드립니다.