이 문서는 지원되지 않는 버전의 PostgreSQL을위한 것입니다.
당신은에 대해 같은 페이지를 보려고 할 수 있습니다PostgreSQL : 문서 : 17 : 41.10. 메이저 윈 토토 사이트 기능버전 또는 위에 나열된 다른 지원 버전 중 하나입니다.

38.9. 윈 토토 절차

pl/pgsql익숙해 질 수 있습니다 윈 토토 절차를 정의하십시오. 윈 토토 절차가 생성됩니다 그만큼함수 만들기명령, 선언 인수가없는 함수와 반환 유형의 함수윈 토토. 함수는 있어야합니다 받을 것으로 예상 되더라도 논쟁없이 선언 지정된 인수윈 토토 만들기- 윈 토토 인수는를 통해 전달됩니다.TG_ARGV, 아래 설명대로.

언제pl/pgsql함수는입니다 윈 토토라고 불리는 몇 가지 특수 변수가 생성됩니다 최상위 블록에서 자동으로. 그들은 :

NEW

데이터 유형레코드; 가변 보유 새로운 데이터베이스 행삽입/업데이트행 수준 윈 토토의 작동. 이 변수는null명령문 수준 윈 토토 그리고 for삭제운영.

old

데이터 유형레코드; 가변 보유 기존 데이터베이스 행업데이트/삭제로드 레벨 윈 토토의 작동. 이 변수는NULL명령문 수준 윈 토토 그리고 for삽입운영.

tg_name

데이터 유형이름; 변수 실제로 해고 된 방아쇠의 이름이 포함되어 있습니다.

TG_WHEN

데이터 유형텍스트; 둘 중 하나또는이후방아쇠에 따라 정의.

tg_level

데이터 유형텍스트; 둘 중 하나13125_13130또는진술방아쇠에 따라 정의.

TG_OP

데이터 유형텍스트; 문자열삽입, 업데이트, 삭제​​또는Truncate작동 방아쇠가 발사되었습니다.

TG_RELID

데이터 유형OID; 객체 ID 윈 토토 호출을 일으킨 테이블

tg_relname

데이터 유형이름; 이름의 이름 윈 토토 호출을 일으킨 테이블. 이것은 지금입니다 더 이상 사용되지 않았으며 향후 릴리스에서 사라질 수 있습니다. 사용tg_table_name대신.

tg_table_name

데이터 유형이름; 이름의 이름 윈 토토 호출을 일으킨 테이블

tg_table_schema

데이터 유형이름; 이름의 이름 윈 토토 호출을 일으킨 테이블 스키마

tg_nargs

데이터 유형정수; 수 의 윈 토토 절차에 대한 인수윈 토토 만들기진술.

tg_argv []

데이터 유형 배열텍스트; 그만큼 의 논쟁윈 토토 만들기진술. 인덱스는 0. 유효하지 않은 인덱스에서 카운트합니다 (덜 0 이상 또는보다tg_nargs) null 값을 초래합니다.

윈 토토 함수는 중 하나를 반환해야합니다NULL또는 정확히 값을 가진 레코드/행 값 테이블의 구조 윈 토토가 발사되었습니다.

로드 레벨 윈 토토 발사can NULL을 반환하여 윈 토토 관리자에게 나머지 부분을 건너 뛰도록 신호를 보냅니다. 이 행의 작업 (즉, 후속 윈 토토가 발사되지 않음 그리고삽입/업데이트/삭제그렇지 않습니다 이 행에 발생합니다). unnull 값이 반환되면 작업은 해당 행 값을 진행합니다. 행 값을 반환합니다 원래 값과 다르NEW삽입 또는 업데이트 될 행을 변경합니다 (그러나 의 직접적인 효과삭제케이스). 에게 저장할 행을 변경하면 단일을 교체 할 수 있습니다. 직접 값NEW수정NEW또는 완전한 신규를 건설합니다 레코드/행 반환.

A의 반환 값또는이후명령문 수준 윈 토토 또는 an이후로우 레벨 윈 토토는 항상입니다 무시; 그것은 널가 될 수도 있습니다. 그러나 이러한 유형 중 하나 윈 토토는 여전히 전체 작업을 중단 할 수 있습니다. 오류.

예제 38-3윈 토토 프로 시저의 예를 보여줍니다pl/pgsql.

예 38-3. 에이PL/PGSQL윈 토토 프로 시저

이 예제 윈 토토는 행이 삽입 될 때마다 또는 테이블에서 업데이트 된 현재 사용자 이름과 시간은 줄에 찍혔습니다. 그리고 직원의 이름이 있는지 확인합니다 주어지고 급여는 긍정적 인 가치입니다.

테이블 emp 생성 (
    Empname 텍스트,
    급여 정수,
    last_date timestamp,
    last_user 텍스트
);

function emp_stamp ()를 $ emp_stamp $로 윈 토토로 반환합니다
    시작하다
        - empname과 월급이 주어 졌는지 확인하십시오
        new.empname이 null이라면 그렇다면
            'empname은 null이 될 수 없다'는 예외를 높이십시오.
        끝 IF;
        New.salary가 null이라면
            '%는'%가 널 급여를 가질 수 없다 ', new.empname;
        끝 IF;

        - 그녀가 돈을 지불해야 할 때 누가 우리를 위해 일합니까?
        새로운.salary <0이라면
            '%는'%가 부정적인 급여를 가질 수 없습니다 ', new.empname;
        끝 IF;

        - 누가 급여를 바꾸 었는지 기억하십시오
        new.last_date : = current_timestamp;
        new.last_user : = current_user;
        새로운 반환;
    끝;
$ emp_stamp $ language plpgsql;

EMP에 삽입하거나 업데이트하기 전에 Trigger Emp_stamp를 만듭니다
    각 행에 대해 Execute Procedure Emp_stamp ();

테이블에 로그 변경하는 또 다른 방법은 새 생성과 관련이 있습니다. 각 삽입, 업데이트 또는 삭제에 대해 행을 보유하는 테이블 발생합니다. 이 접근법은 감사 변경으로 생각할 수 있습니다. 테이블.예제 38-4감사 윈 토토 절차의 예를 보여줍니다pl/pgsql.

예 38-4. 에이pl/pgsql윈 토토 절차 감사

이 예제 윈 토토는 삽입, 업데이트 또는 에서 행 삭제emp테이블은 기록 된 (즉, 감사)emp_audit테이블. 현재 시간과 사용자 이름 작업 유형과 함께 행에 스탬핑됩니다. 그것에 대해 수행했습니다.

테이블 emp 만들기 (
    embname 텍스트가 null,
    급여 정수
);

테이블 작성 emp_audit (
    char (1) null이 아닌 작전,
    스탬프 타임 스탬프가 널 있지 않음,
    userID 텍스트는 null이 아닙니다.
    embname 텍스트가 null,
    급여 정수
);

함수 process_emp_audit ()를 $ emp_audit $로 반환합니다
    시작하다
        -
        - EMP에서 수행 된 작업을 반영하기 위해 EMP_AUDIT에서 행을 만듭니다.
        - 특수 변수 TG_OP를 사용하여 작업을 수행하십시오.
        -
        if (tg_op = 'delete') 그러면
            emp_audit에 삽입 'd', now (), user, old.*;
            옛날 복귀;
        elsif (tg_op = 'update')
            emp_audit에 삽입 'u', now (), 사용자, 새로운.*;
            새로운 반환;
        elsif (tg_op = 'insert')
            emp_audit에 삽입 'i', now (), user, new.*;
            새로운 반환;
        끝 IF;
        널 리턴; - 결과는 방아쇠 이후에 무시됩니다.
    끝;
$ emp_audit $ 언어 plpgsql;

윈 토토 emp_audit을 만듭니다
EMP에 삽입 또는 업데이트 또는 삭제 후
    각 행에 대해 프로 시저 Execute process_emp_audit ();

윈 토토의 사용은 다른 사람의 요약 테이블을 유지하는 것입니다. 테이블. 결과 요약은 원본 대신에 사용할 수 있습니다. 특정 쿼리 용 테이블 - 종종 실행 시간이 크게 줄어 듭니다. 이 기술은 일반적으로 데이터웨어 하우징에 사용됩니다. 측정 또는 관찰 된 데이터 테이블 (사실 테이블이라고 함) 매우 큰.예 38-5윈 토토 절차의 예를 보여줍니다PL/PGSQL에 대한 요약 테이블을 유지합니다 데이터웨어 하우스의 사실 테이블.

예 38-5. 에이pl/pgsql유지 관리 절차 요약 테이블

여기에 자세히 설명 된 스키마는 부분적으로입니다.식료품 점예제데이터웨어 하우스 툴킷By Ralph Kimball.

-
- 메인 테이블 - 시간 차원 및 판매 사실.
-
테이블 생성 time_dimension (
    time_key 정수가 null,
    day_of_week 정수 NOT NULL,
    day_of_month Integer Not Null,
    월 정수가 널이 아닌
    쿼터 정수는 null이 아닙니다.
    연도 정수는 null이 아닙니다
);
time_dimension (time_key)에서 고유 한 색인 time_dimension_key를 만듭니다.

테이블 생성 sales_fact (
    time_key 정수가 null,
    Product_key Integer Not Null,
    store_key 정수 NOT NULL,
    득
    Unit_Sold Integer Not Null,
    숫자 숫자 숫자 (12,2)는 널 not
);
sales_fact (time_key)에서 색인 sales_fact_time을 만듭니다.

-
- 요약 테이블 - 시간별 판매.
-
테이블 생성 sales_summary_bytime (
    time_key 정수가 null,
    득
    Unit_SOLD 숫자 (12) NOT NULL,
    aMond_cost 숫자 (15,2)는 null이 아닙니다
);
sales_summary_bytime (time_key)에서 고유 한 인덱스 sales_summary_bytime_key 만들기;

-
- 기능 및 윈 토토는 업데이트, 삽입, 삭제시 요약 된 열을 수정합니다.
-
함수를 만들거나 교체하십시오. maint_sales_summary_bytime ()은 trigger를 $ maint_sales_summary_bytime $로 반환합니다
    선언하다
        delta_time_key 정수;
        delta_amount_sold 숫자 (15,2);
        delta_units_sold 숫자 (12);
        delta_amount_cost 숫자 (15,2);
    시작하다

        - 증분/감소량을 계산하십시오.
        if (tg_op = 'delete') 그러면

            delta_time_key = old.time_key;
            delta_amount_sold = -1 * old.amount_sold;
            delta_units_sold = -1 * old.units_sold;
            delta_amount_cost = -1 * old.amount_cost;

        elsif (tg_op = 'update')

            - time_key를 변경하는 업데이트 금지 -
            - (Delete + Insert가 가장 많이
            - 변경이 이루어집니다).
            if (old.time_key! = new.time_key) 그러면
                'Time_key의 업데이트 : % - % 허용되지 않음', old.time_key, new.time_key;
            끝 IF;

            delta_time_key = old.time_key;
            delta_amount_sold = new.amount_sold -Old.amount_sold;
            delta_units_sold = new.units_sold -Old.units_sold;
            delta_amount_cost = new.amount_cost -Old.amount_cost;

        elsif (tg_op = 'insert')

            delta_time_key = new.time_key;
            delta_amount_sold = new.amount_sold;
            delta_units_sold = new.units_sold;
            delta_amount_cost = new.amount_cost;

        끝 IF;

        - 새 값으로 요약 행을 삽입하거나 업데이트하십시오.
        << insert_update 
        고리
            SALLE_SUMMARY_BYTIME 업데이트
                set aveS_SOLD = aMber_sold + delta_amount_sold,
                    units_sold = units_sold + delta_units_sold,
                    aMber_cost = aMber_cost + delta_amount_cost
                여기서 time_key = delta_time_key;

            발견되면 insert_update를 종료합니다.

            시작하다
                sales_summary_bytime에 삽입 (
                            time_key,
                            aMber_sold,
                            Unit_Sold,
                            aMber_cost)
                    값 (
                            delta_time_key,
                            delta_amount_sold,
                            delta_units_sold,
                            delta_amount_cost
                           );

                insert_update 종료;

            예외
                그럼에도 불구하고
                    - 아무것도하지 않습니다
            끝;
        엔드 루프 insert_update;

        널 리턴;

    끝;
$ maint_sales_summary_bytime $ 언어 plpgsql;

윈 토토 maint_sales_summary_bytime을 만듭니다
sales_fact에서 삽입 또는 업데이트 또는 삭제 후
    각 행에 대해 실행 절차 maint_sales_summary_bytime ();

sales_fact 값 (1,1,1,10,3,15)에 삽입;
Sales_Fact 값 (1,2,1,20,5,35)에 삽입;
sales_fact 값에 삽입 (2,2,1,40,15,135);
Sales_Fact 값 (2,3,1,10,1,13)에 삽입;
sales_summary_bytime에서 *를 선택하십시오.
sales_fact에서 삭제하는 곳에서 product_key = 1;
sales_summary_bytime에서 *를 선택하십시오.
Sales_fack Set units_sold = units_sold * 2 업데이트;
sales _summary_bytime에서 * 선택 *