2010-01-20 3 views
3

저는 최근에 PostgreSQL을 사용하기 시작했습니다. 그리고 나는 그것을 이해 했으므로 "올바른 방법"으로 일하려고 노력하고 있습니다. 가능한 한 클라이언트가 아닌 데이터베이스 서버에 많은 작업을 넣는 것을 의미합니다.PostgreSQL 삽입은 다른 테이블의 데이터에 따라 다릅니 까?

그래서 테이블에 데이터를 추가하는 PL/pgSQL 함수를 만들었습니다. 그 테이블에 기본 키 제약 조건을 설정했기 때문에 새로운 데이터를 추가하려고 할 때 참조 된 키가 존재하지 않을 수도 있습니다. 예외를 추가하면 키를 생성 한 다음 새로운 행.

이것은 나를 위해 만족 스럽지만,이 "올바른 방법"을 처리하는지 궁금합니다. 나는 이러한 사용자 정의 함수를 설계하는 지침을 찾기 위해 노력했지만 실제로 도움이되는 어떤 것도 찾지 못했습니다.

CREATE OR REPLACE FUNCTION add_product_price_promo_xml(v_product_code varchar, v_description varchar, v_product_group varchar, 
                 v_mixmatch_id integer, v_price_at date, v_cost_price numeric, v_sales_price numeric, 
                 v_tax_rate integer) RETURNS void AS $$ 
BEGIN 
    INSERT INTO product_prices (product_code , mixmatch_id , price_at , cost_price , sales_price , tax_rate) VALUES 
           (v_product_code, v_mixmatch_id, v_price_at, v_cost_price, v_sales_price, v_tax_rate); 
EXCEPTION WHEN foreign_key_violation THEN 
    INSERT INTO products (code, description, product_group) VALUES (v_product_code, v_description, v_product_group); 
    PERFORM add_product_price_promo_xml($1, $2, $3, $4, $5, $6, $7, $8); 
END; 
$$ LANGUAGE plpgsql; 

문제의 데이터베이스는보고를하고 항목 전체 가격 업데이트 및 새 항목 매일 등록 가져 오는 것 사용하는 것입니다,하지만 새로운있는 항목을 알 수 없습니다 어느 사람이 늙은.

답변

4

아니요! WRONG WAY 죄송합니다. 저는 수년간 postgresql을 사용해 왔지만 이것은 좋은 생각이 아닙니다. 올바른 방법은 (1) 임시 테이블을 만들고 (2) 위반이있는 곳을 업데이트하고 (3) 위반이없는 곳에 삽입하는 것입니다. 나는 페이지 8.4 사용하여 당신에게 조각을 보여주지 :

CREATE TEMP TABLE temp_table (
    LIKE table INCLUDING INDEXES INCLUDING CONSTRAINTS 
); 

는 그런 다음, temp_table에 당신의 재료를 모두 넣고이 두 명령을 실행합니다.

관심이 있고 충분한 mem이 있으면 트랜잭션으로 처리 할 수 ​​있습니다. 이 방법은 내부적으로 많은 양의 checkpoints을 생성하지 않기 때문에 확장됩니다. 도 대폭입니다. 귀하의 현재 방식은 pseudo-merge routine on Varlena in 2006으로 게시되었으며, 저에게 맞습니까? 그리고 많은 사람들이 물었습니다. 나는 그것을 필요로하지 않는다. 그래서 나는 그것을 피하는 것이 좋다.

+0

@EvanCarrorll, 정확하게 'INSERT INTO ...'질의가 무엇을하고 있는지 설명해 주시겠습니까? – jeffdill2

+0

@ jeffdill2 이것은 현재로서는 좋지 않은 조언이며, 전적으로 업데이트 할 것입니다. –

+0

은 문제가되지 않습니다. 나는 실제로 그것을 알아 냈다. 방금 LEFT JOIN을 사용하고 조인 된 테이블에서 WHERE ... IS NULL을 확인하여 비슷한 접근 방식을 구현했습니다. – jeffdill2

0

당신은 실제로 괜찮습니다. 스토어드 프로 시저를 사용하면서 PostgreSQL의 구버전을 타겟으로하지 않는다면 이름을 인자로 참조 할 때 안심할 수 있도록 함수의 부울 반환 값을 제공하는 것이 좋습니다 (이 경우 이전 버전의 PostgreSQL을 필요로합니다. DECLARE 섹션을 추가하십시오).

Pl/PgSQL에서 저장 프로 시저를 작성하는 데 많은 자료가있는 PostgreSQL (Developer's Library) by Korry Douglas 책을 강력하게 추천합니다. Postgres를 사용하여 복잡한 문제를 해결하기위한 베스트 프랙티스와 영리한 트릭을 자주 논의하므로 PostgreSQL 커뮤니티의 저명한 회원의 블로그 게시물을 집계하는 Planet PostgreSQL 포털을 따르는 것이 좋습니다. 행운을 빕니다!

0

정상적인 경우 예외를 throw하지 않고 실행해야하는 코드를 작성하는 것이 더 효과적이라고 생각합니다. 당신이있어 때문에 PL/pgSQL의 어쨌든, 왜로 쓸 수 없습니다 : 핸들러가 하나의 반대로 예외 핸들러가 블록과 관련된 더 많은 오버 헤드가있다는 PL/pgSQL의 문서에 따르면

CREATE OR REPLACE FUNCTION add_product_price_promo_xml(v_product_code varchar, 
                 v_description varchar, 
                 v_product_group varchar, 
                 v_mixmatch_id integer, 
                 v_price_at date, 
                 v_cost_price numeric, 
                 v_sales_price numeric, 
                 v_tax_rate integer) 
    RETURNS void AS $$ 
DECLARE 
    n_count numeric; 
BEGIN 
    SELECT COUNT(*) 
    FROM products 
    INTO n_count 
    WHERE code = v_product_code; -- or whatever the join criteria should be 

    IF n_count = 0 THEN 
    INSERT INTO products 
     (code, description, product_group) 
    VALUES 
     (v_product_code, v_description, v_product_group); 
    END IF; 

    INSERT INTO product_prices 
    (product_code, mixmatch_id, price_at, 
    cost_price, sales_price, tax_rate) 
    VALUES 
    (v_product_code, v_mixmatch_id, v_price_at, 
    v_cost_price, v_sales_price, v_tax_rate); 
END; 
$$ LANGUAGE plpgsql; 

, 그래서 약간의 오버 헤드를 줄일 수 있습니다.

공유하고 즐기십시오.

관련 문제