초보 디비사용자 입니다.
Trigger를 사용하려고 test를 하던중 이상한 현상을 발견했습니다.
현재 Postgresql-7.1.2를 사용 하고 있습니다.
조만간에 버전을 올릴 계획인데, 상위 버전에서도 아래와 같이 실행이 될지 궁금합니다.
===== 실행문 =========
DROP TRIGGER CHK_TG ON CHECK2;
DROP FUNCTION CHK2_TR();
DROP TABLE CHECK2;
DROP TABLE CCK;
DROP SEQUENCE cck_cck_no_seq;
DROP SEQUENCE check2_chk_no_seq;
CREATE TABLE CHECK2(
CHK_NO SERIAL PRIMARY KEY,
CHK_NAME VARCHAR,
CHK_V1 INT NOT NULL DEFAULT 0,
CHK_V2 INT NOT NULL DEFAULT 0);
CREATE TABLE CCK(
CCK_NO SERIAL PRIMARY KEY,
CCK_NAME VARCHAR,
CCK_V INT);
CREATE FUNCTION CHK2_TR() RETURNS OPAQUE AS '
BEGIN
IF ((SELECT CHK_V1 FROM CHECK2 WHERE CHK_NO=old.CHK_NO)=NEW.CHK_V2) THEN
INSERT INTO CCK(CCK_NAME,CCK_V) VALUES(old.CHK_NAME,new.CHK_V2);
DELETE FROM CHECK2 WHERE CHK_NO=OLD.CHK_NO;
END IF;
return old;
END;
' LANGUAGE 'plpgsql';
CREATE TRIGGER CHK_TG AFTER UPDATE ON CHECK2
FOR EACH ROW EXECUTE PROCEDURE CHK2_TR();
INSERT INTO CHECK2(CHK_NAME,CHK_V1) values('빵',3000);
INSERT INTO CHECK2(CHK_NAME,CHK_V1) values('쿠키',2000);
INSERT INTO CHECK2(CHK_NAME,CHK_V1) values('도너츠',5000);
SELECT * FROM CHECK2;
SELECT * FROM CCK;
UPDATE CHECK2 SET CHK_V2='3000' WHERE CHK_NO=1;
SELECT * FROM CHECK2;
SELECT * FROM CCK;
UPDATE CHECK2 SET CHK_V2='4000' WHERE CHK_NO=2;
SELECT * FROM CHECK2;
SELECT * FROM CCK;
UPDATE CHECK2 SET CHK_V1='4000' WHERE CHK_NO=2;
SELECT * FROM CHECK2;
SELECT * FROM CCK;
=========== 실행 결과 ============
DROP
DROP
DROP
DROP
DROP
DROP
psql:./new/test2:15: NOTICE: CREATE TABLE will create implicit sequence 'check2_chk_no_seq' for SERIAL column 'check2.chk_no'
psql:./new/test2:15: NOTICE: CREATE TABLE/PRIMARY KEY will create implicit index 'check2_pkey' for table 'check2'
CREATE
psql:./new/test2:20: NOTICE: CREATE TABLE will create implicit sequence 'cck_cck_no_seq' for SERIAL column 'cck.cck_no'
psql:./new/test2:20: NOTICE: CREATE TABLE/PRIMARY KEY will create implicit index 'cck_pkey' for table 'cck'
CREATE
CREATE
CREATE
psql:./new/test2:36: NOTICE: check2_chk_no_seq.nextval: sequence was re-created
INSERT 317426 1
INSERT 317427 1
INSERT 317428 1
chk_no | chk_name | chk_v1 | chk_v2
--------+----------+--------+--------
1 | 빵 | 3000 | 0
2 | 쿠키 | 2000 | 0
3 | 도너츠 | 5000 | 0
(3 rows)
cck_no | cck_name | cck_v
--------+----------+-------
(0 rows)
psql:./new/test2:43: NOTICE: cck_cck_no_seq.nextval: sequence was re-created
UPDATE 1
chk_no | chk_name | chk_v1 | chk_v2
--------+----------+--------+--------
2 | 쿠키 | 2000 | 0
3 | 도너츠 | 5000 | 0
(2 rows)
cck_no | cck_name | cck_v
--------+----------+-------
1 | 빵 | 3000
(1 row)
UPDATE 1
chk_no | chk_name | chk_v1 | chk_v2
--------+----------+--------+--------
3 | 도너츠 | 5000 | 0
2 | 쿠키 | 2000 | 4000
(2 rows)
cck_no | cck_name | cck_v
--------+----------+-------
1 | 빵 | 3000
(1 row)
UPDATE 1
chk_no | chk_name | chk_v1 | chk_v2
--------+----------+--------+--------
3 | 도너츠 | 5000 | 0
(1 row)
cck_no | cck_name | cck_v
--------+----------+-------
1 | 빵 | 3000
2 | 쿠키 | 4000
(2 rows)
======= 궁금한점 ==========
함수에서 chk_v2값을 업데이트 할때..
기존에 있던 chk_v1값과 비교하여 값이 같으면
check2테이블에서 삭제하고 cck테이블에 인서트 하게 되어 있습니다.
chk_v2값을 업데이트 할때는 이상없이 동작합니다.
(사실 저야 위 처럼 동작하는게 더없이 좋지만..)
이상한 점은 chk_v1값을 업데이트할때 old.chk_v1과 new.chk_v2를 비교 하고 같으면 해당 row를 삭제하고 cck테이블에 new.chk_v2를 입력 하게 되어 있으므로 에러 발생 내지는 실행이 되지않아야 하는데..
위의 실행결과는 new.chk_v1과 old.chk_v2와 비교 하고 값이 같으므로 해당 row를 삭제 하고 cck테이블에 chk_v1값을 입력합니다.
아직 Trigger나 function에 대해서 잘 알지는 못하지만 DB에서 알아서 비교 해야될 값들을 설정해주는 것인지 궁금합니다.
고수님들의 한수 가르침을 기다립니다.
긴글읽어 주셔서 감사합니다. :)
|