database.sarang.net
UserID
Passwd
Database
DBMS
MySQL
ㆍPostgreSQL
Firebird
Oracle
Informix
Sybase
MS-SQL
DB2
Cache
CUBRID
LDAP
ALTIBASE
Tibero
DB 문서들
스터디
Community
공지사항
자유게시판
구인|구직
DSN 갤러리
도움주신분들
Admin
운영게시판
최근게시물
PostgreSQL Q&A 7555 게시물 읽기
No. 7555
외래키와 트리거에 대해 질문 드리겠습니다.
작성자
김하늘
작성일
2008-11-11 12:09
조회수
6,677

안녕하세요. 오랜만에 글을 올리네요.

트리거와 관련해서 질문을 드리겠습니다.


-- 부품 테이블입니다.

CREATE TABLE part

(

  partno character(12) NOT NULL,

  partname character varying(50) NOT NULL,

  ...(생략)

  CONSTRAINT part_pkey PRIMARY KEY (partno)

);


-- 부품 초기재고 테이블입니다.

CREATE TABLE initstock

(

  partno character(12) NOT NULL,

  qty integer NOT NULL,

  registered timestamp with time zone NOT NULL DEFAULT now(),

 ...(생략)

   CONSTRAINT initstock_partno_fkey FOREIGN KEY (partno)

      REFERENCES part (partno) MATCH SIMPLE

      ON UPDATE CASCADE ON DELETE NO ACTION

);


-- 재고 테이블입니다.

CREATE TABLE stock

(

  partno character(12) NOT NULL,

  qty integer NOT NULL DEFAULT 0,

  CONSTRAINT stock_pkey PRIMARY KEY (partno),

  CONSTRAINT stock_partno_fkey FOREIGN KEY (partno)

      REFERENCES part (partno) MATCH SIMPLE

      ON UPDATE CASCADE ON DELETE CASCADE

);



-- 초기재고 갱신 트리거는 아래와 같습니다.

CREATE OR REPLACE FUNCTION initstock_upd()

  RETURNS trigger AS

$BODY$

begin

  if old.partno = new.partno then

    update stock set qty = qty + (new.qty - old.qty) where partno = new.partno;

  else

    update stock set qty = qty - old.qty where partno = old.partno;

    update stock set qty = qty + new.qty where partno = new.partno;

  end if;

  return null;

end;

$BODY$

  LANGUAGE 'plpgsql' VOLATILE

  COST 100;


CREATE TRIGGER initstock_upd_trig

  AFTER UPDATE

  ON initstock

  FOR EACH ROW

  EXECUTE PROCEDURE initstock_upd();


--------------------

초기재고를 추가와 삭제시 재고 테이블의 재고수량이 갱신은 정확히 됩니다.

초기재고의 값을 변경해도 반영이 잘 되고요.


문제는 부품(part) 테이블의 partno(PK)가 변경이 될 경우 초기재고(initstock) 테이블과 재고(stock)테이블이 partno를 외래키로 참조하는데

초기재고의 갱신 트리거 함수가 작동되면서 재고가 초기재고 수량의 2배로 증가한다는 겁니다.


이걸 해결할 방법은 어떤게 있습니까?

제가 떠오르는 방법은 아래와 같은데... 더 좋은 방법이나 구체적인 방법 좀 조언 부탁합니다.

1. 트리거 함수를 제거하고 응용프로그램에서 처리한다.

2. 트리거 함수에서 처리하는 방법(이게 가능한지 모르겠습니다)

3. 외래키 처리방식을 변경한다.(변경이 안되는 다른 키를 추가해서 참조한다)


감사합니다.

이 글에 대한 댓글이 총 4건 있습니다.

트리거 체크시


if old.partno = new.partno then 체크문을


IF( TG_OP = 'ACTION' ) THEN 변경해서


해보시기 바랍니다.


저기 ACTION은 UPDATE, INSERT, DELETE로 변경해서 사용해야 합니다.


그럼

김병석(byung82)님이 2008-11-11 15:10에 작성한 댓글입니다.

먼저,답변을 주셔서 감사합니다.

아래와 같이 해서 partno를 변경해 보았더니 전과같이 값이 2배로 증가합니다.


partno 변경 자체가 update로 간주되는 모양인데요.


CREATE OR REPLACE FUNCTION initstock_upd()

  RETURNS trigger AS

$BODY$

begin

  if TG_OP = 'UPDATE' then

      if old.partno = new.partno then

        update stock set qty = qty + (new.qty - old.qty) where partno = new.partno;

      else

        update stock set qty = qty - old.qty where partno = old.partno;

        update stock set qty = qty + new.qty where partno = new.partno;

      end if;

  end if;

  return null;

end;

$BODY$

  LANGUAGE 'plpgsql' VOLATILE

  COST 100;

ALTER FUNCTION initstock_upd() OWNER TO changuk;

김하늘님이 2008-11-11 16:23에 작성한 댓글입니다. Edit

INSERT, UPDATE도 NEW Instance입니다.

OLD Instance를 사용하시면 안됩니다


그렇기 때문에

old.partno = new.partno는 제거하시고


update stock set qty = qty + new.qty where partno = new.partno


이것만 존재하면 될거라 보입니다.


그리고 테이블상에 트리가거 AFTER인지 BEFORE인지도 알려주시기 바랍니다.


테이블상에


CREATE TABLE stock

 

(

 

  partno character(12) NOT NULL,

 

  qty integer NOT NULL DEFAULT 0,

 

  CONSTRAINT stock_pkey PRIMARY KEY (partno),

 

  CONSTRAINT stock_partno_fkey FOREIGN KEY (partno)

 

      REFERENCES part (partno) MATCH SIMPLE

 

      ON UPDATE CASCADE ON DELETE CASCADE

 

);


보면 UPDATE시 CASCADE로 되어 있는데 NO ACTION으로 수정해보시고


확인도 해보시기 바랍니다.



그러면

김병석(byung82)님이 2008-11-11 17:38에 작성한 댓글입니다.
이 댓글은 2008-11-11 17:40에 마지막으로 수정되었습니다.

추가답변 감사합니다.

말씀하신대로 해봤습니다.

그러나, part 테이블의 partno 값이 변경될 경우 stock 테이블의 partno이 변경되지 않습니다.

당연히 ON UPDATE NO ACTION 이기 때문이겠죠. 물론 값 증가는 일어나지 않고.

변경이 되어도 재고수량이 정확해야 합니다.


책을 뒤적이고 있는데 잘 안되는군요. ^^;

조언 계속 기다리겠습니다.

김하늘님이 2008-11-12 09:06에 작성한 댓글입니다. Edit
[Top]
No.
제목
작성자
작성일
조회
75588.3버젼에 slony-I설치 해보신분!! [1]
서정주
2008-11-13
6417
7557설치후 에러 메세지와 실행 관련 해서 질문좀 드릴게요. [2]
최훈
2008-11-13
9992
7556접속 비밀번호에 대해서.. [1]
관식
2008-11-12
6602
7555외래키와 트리거에 대해 질문 드리겠습니다. [4]
김하늘
2008-11-11
6677
7553새로 설치 후 스타트가 안되요 [1]
김태규
2008-11-06
6162
7552[급질]postgreSQL 와전 초보입니다. 8.1 -> 8.3 업그레이드 질문좀..
이태영
2008-11-04
6802
7551postgre Sql windows vista 설치 하는 방법 [5]
김정길
2008-10-31
6313
Valid XHTML 1.0!
All about the DATABASE... Copyleft 1999-2024 DSN, All rights reserved.
작업시간: 0.018초, 이곳 서비스는
	PostgreSQL v16.2로 자료를 관리합니다