PostgreSQL의 트리거와 펑션 예제를 만들어 봤다.

자료를 찾는데 너무 힘들어서 나중에 잊기전에 정리해봤다.




● 우선 테스트용 테이블 작성 


CREATE TABLE datalog(

    logtime timestamp PRIMARY KEY,

    data varchar,

    content varchar

);


* 테이블 지우기

DROP TABLE datalog;


● 펑션(Function) 함수 예제

    이 함수가 실행되면 지정 테이블의 레코드가 10개를 넘으면 가장 오래된 것부터 지운다.


CREATE FUNCTION data_fun() RETURNS trigger AS $data_fun$

    DECLARE

rowcount integer;

        delcount integer;

        maxcount integer;

    BEGIN

        maxcount := 10;

        SELECT count(*) logtime into rowcount  FROM datalog;

        delcount := rowcount - maxcount + 1;


        IF delcount > 0 THEN

   DELETE FROM datalog WHERE logtime IN (SELECT logtime FROM datalog ORDER BY logtime LIMIT delcount);

        END IF;


RETURN NEW;

    END;

$data_fun$ LANGUAGE plpgsql;


* 펑션 지우기

DROP FUNCTION data_fun();


● 트리거(Trigger) 함수 예제

    지정 Table에서 추가나 변경이 이루어질 때 지정 펑션이 실행된다.


CREATE TRIGGER data_trg BEFORE INSERT OR UPDATE ON datalog

    FOR EACH ROW EXECUTE PROCEDURE data_fun();


* 트리거 지우기

DROP TRIGGER data_trg ON datalog;



● 테스트용 데이터


insert into datalog(logtime, data) values('2015-01-01 12:12:01', 'aa');

insert into datalog(logtime, data) values('2015-01-01 12:12:02', 'aa');

insert into datalog(logtime, data) values('2015-01-01 12:12:03', 'aa');

insert into datalog(logtime, data) values('2015-01-01 12:12:04', 'aa');

insert into datalog(logtime, data) values('2015-01-01 12:12:05', 'aa');

insert into datalog(logtime, data) values('2015-01-01 12:12:06', 'aa');

insert into datalog(logtime, data) values('2015-01-01 12:12:07', 'aa');

insert into datalog(logtime, data) values('2015-01-01 12:12:08', 'aa');

insert into datalog(logtime, data) values('2015-01-01 12:12:09', 'aa');

insert into datalog(logtime, data) values('2015-01-01 12:13:01', 'aa');

insert into datalog(logtime, data) values('2015-01-01 12:13:02', 'aa');

insert into datalog(logtime, data) values('2015-01-01 12:13:03', 'aa');

insert into datalog(logtime, data) values('2015-01-01 12:13:04', 'aa');

insert into datalog(logtime, data) values('2015-01-01 12:13:05', 'aa');

insert into datalog(logtime, data) values('2015-01-01 12:13:06', 'aa');

insert into datalog(logtime, data) values('2015-01-01 12:13:07', 'aa');

insert into datalog(logtime, data) values('2015-01-01 12:13:08', 'aa');

insert into datalog(logtime, data) values('2015-01-01 12:13:09', 'aa');


위의 데이터를 입력하면 로그는 10개 행만 테이블에 저장된다.
데이터를 추가하기 전에 트리거의 연결된 펑션이 실행되어
테이블의 행이 10개를 넘어가면 가장 옛날 데이터를 삭제한다.




Posted by 떡잎



Firebird의 Firebird ISQL Tool을 실행해서 아래 녹색 상자의 Source를 전체를 붙여 넣어보면 어떻게 동작하는지 대충 알 수 있다.

create database 'TestAutoNoDb.fdb' user 'sysdba' password 'masterkey';

set autoddl off;

create table AutoNoTable (
  AutoId   integer not null,
  Fld_Int  integer,
  Fld_Char char(200),
 
  constraint pk_AutoNoTable primary key (AutoId)
);

create generator gen_AutoId;

set term ^;

create trigger trg_AutoNoTable_SeqNo for AutoNoTable
active before insert position 1
AS
begin
  if (new.AutoId is null) then
    new.AutoId = gen_id(gen_AutoId, 1);
end
^
commit work^

set term ; ^

insert into AutoNoTable (Fld_Int, Fld_Char) values (1, 'one');
insert into AutoNoTable (Fld_Int, Fld_Char) values (2, 'two');
insert into AutoNoTable (Fld_Int, Fld_Char) values (3, 'three');

commit work;

select * from AutoNoTable;



설명

// Database 만들기
create database 'TestAutoNoDb.fdb' user 'sysdba' password 'masterkey';

// 자동 Commit mode off(?)
set autoddl off;

// 자동 연번 Test용 Table 만들기
create table AutoNoTable (
  AutoId   integer not null,
  Fld_Int  integer,
  Fld_Char char(200),
 
  constraint pk_AutoNoTable primary key (AutoId)
);

// 자동 연번용 generator 만들기
create generator gen_AutoId;

// 자동 연번 Trigger 만들기
set term ^;

create trigger trg_AutoNoTable_SeqNo for AutoNoTable
active before insert position 1
AS
begin
  if (new.AutoId is null) then
    new.AutoId = gen_id(gen_AutoId, 1);
end
^
commit work^

// 데이터 추가
set term ; ^

insert into AutoNoTable (Fld_Int, Fld_Char) values (1, 'one');
insert into AutoNoTable (Fld_Int, Fld_Char) values (2, 'two');
insert into AutoNoTable (Fld_Int, Fld_Char) values (3, 'three');

commit work;

// 데이터 가져오기
select * from AutoNoTable;


실행 결과

      AUTOID      FLD_INT FLD_CHAR
============ ============ ===========
          1            1 one
           2            2 two
           3            3 three

AUTOID와 추가 하지 않아도 자동으로 연번이 생성됨

주의) 이 트리거에 문제점이 하나 있다.
연번이 가장 큰 숫자에서 시작하지 않는다. -.-;;
그래서 이 트리거를 사용하지 않고 인위적으로 AUTOID field에 높은 번호를 입력하면
자동으로 AutoID가 입력될 때 같은 번호가 나오면 Error가 발생되게 된다.


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

참고

위 Source를 Firebird ISQL Tool에 붙이려면 Firebird ISQL Tool의 Caption bar에서 오른쪽 click하면 popup menu가 표시되고 편집 > 붙여넣기(P)를 선택하면 된다.

Posted by 떡잎
BLOG main image
프로그래밍 공부하면서 써가는 개인 노트 (따라서 여기에 씌여있는 소스의 신빙성을 보장 못함 -.-;;) 이 블로그 보면서 틀린 점이 있으면 꼬옥 알려주세요. by 띠리

공지사항

카테고리

분류 전체보기 (323)
Win32 SDK 초보 (27)
통신관련 (11)
MFC TIP (20)
C/C++ TIP (10)
개발기타 (10)
링크 (2)
견물생심 (24)
이것저것 (8)
용어메모 (3)
데이터베이스 (32)
비주얼 베이직 (10)
하드웨어 (3)
C# (42)
Xcode (3)
델파이 (82)
홈페이지 (5)
MindStorm (0)
낙서 (5)
스크래치 (0)
기타 (6)
아두이노 (1)
라즈베리파이 (2)
안드로이드 (6)
파이썬 (0)
WEB (2)
Total : 955,947
Today : 40 Yesterday : 355