41.10. 윈 토토 기능#

PL/pgSQL데이터 변경 또는 데이터베이스 이벤트에 대한 윈 토토 기능을 정의하는 데 사용할 수 있습니다. 윈 토토 함수는 다음을 사용하여 생성됩니다.함수 생성명령, 인수가 없고 반환 유형이 있는 함수로 선언함윈 토토(데이터 변경 윈 토토의 경우) 또는event_trigger(데이터베이스 이벤트 윈 토토용). 이름이 지정된 특수 지역 변수TG_뭔가호출을 윈 토토한 조건을 설명하기 위해 자동으로 정의됩니다.

41.10.1. 데이터 변경 시 윈 토토#

A 스포츠 토토 사이트 :인수가 없고 반환 유형이 다음과 같은 함수로 선언되었습니다.윈 토토. 함수는 지정된 일부 인수를 수신할 것으로 예상되는 경우에도 인수 없이 선언되어야 합니다.윈 토토 생성— 이러한 인수는 다음을 통해 전달됩니다.TG_ARGV, 아래 설명대로.

PL/pgSQL함수가 윈 토토로 호출되면 여러 특수 변수가 최상위 블록에 자동으로 생성됩니다. 그들은:

신규 기록 #

다음에 대한 새 데이터베이스 행삽입/업데이트행 수준 윈 토토의 작업. 이 변수는 명령문 수준 윈 토토 및 for에서 null입니다.삭제작업.

오래된 기록 #

다음에 대한 이전 데이터베이스 행업데이트/삭제행 수준 윈 토토의 작업. 이 변수는 명령문 수준 윈 토토 및 for에서 null입니다.삽입작업.

TG_NAME 이름 #

실행된 윈 토토의 이름.

TG_WHEN 텍스트 #

이전, 이후또는대신, 윈 토토 정의에 따라 다름.

TG_LEVEL 텍스트 #

ROW또는진술문, 윈 토토 정의에 따라 다름.

TG_OP 텍스트 #

윈 토토가 실행된 작업:삽입, 업데이트, 삭제또는잘라내기.

TG_RELID oid(참조pg_class.oid) #

윈 토토 호출을 발생시킨 테이블의 객체 ID.

TG_RELNAME 이름 #

15917_16030TG_TABLE_NAME대신.

TG_TABLE_NAME 이름 #

윈 토토 호출을 발생시킨 테이블입니다.

TG_TABLE_SCHEMA 이름 #

윈 토토 호출을 발생시킨 테이블의 스키마.

TG_NARGS 정수 #

에서 윈 토토 함수에 제공된 인수 수윈 토토 생성성명.

TG_ARGV 텍스트[] #

의 인수윈 토토 생성성명. 인덱스는 0부터 계산됩니다. 잘못된 인덱스(0보다 작거나 크거나 같음)tg_nargs) 결과는 null 값입니다.

윈 토토 함수는 다음 중 하나를 반환해야 합니다.NULL또는 윈 토토가 실행된 테이블의 구조와 정확히 일치하는 레코드/행 값

행 수준 윈 토토가 실행됨이전널을 반환하여 윈 토토 관리자에게 이 행에 대한 나머지 작업을 건너뛰도록 신호를 보낼 수 있습니다(즉, 후속 윈 토토는 실행되지 않으며삽입/업데이트/삭제이 행에서는 발생하지 않습니다). Null이 아닌 값이 반환되면 해당 행 값으로 작업이 진행됩니다. 원래 값과 다른 행 값을 반환합니다.신규삽입되거나 업데이트될 행을 변경합니다. 따라서 윈 토토 함수가 행 값을 변경하지 않고 윈 토토 작업이 정상적으로 성공하기를 원하는 경우,신규(또는 이와 동일한 값)이 반환되어야 합니다. 저장할 행을 변경하려면 다음에서 직접 단일 값을 바꿀 수 있습니다.신규그리고 수정된 내용을 반환신규또는 반환할 완전한 새 레코드/행을 작성합니다. 윈 토토 전의 경우삭제, 반환된 값은 직접적인 영향을 미치지 않지만 윈 토토 작업을 계속하려면 null이 아니어야 합니다. 참고하세요신규null입니다.삭제윈 토토이므로 이를 반환하는 것은 일반적으로 합리적이지 않습니다. 의 일반적인 관용어삭제윈 토토가 반환됩니다오래된.

대신윈 토토(항상 행 수준 윈 토토이며 뷰에서만 사용할 수 있음)는 null을 반환하여 업데이트를 수행하지 않았으며 이 행에 대한 나머지 작업을 건너뛰어야 함을 알릴 수 있습니다(즉, 후속 윈 토토가 실행되지 않고 행이 주변에 대한 행의 영향을 받는 상태로 계산되지 않습니다.삽입/업데이트/삭제). 그렇지 않으면 윈 토토가 요청된 작업을 수행했음을 알리기 위해 null이 아닌 값이 반환되어야 합니다. 에 대한삽입그리고업데이트작업, 반환 값은 다음과 같아야 합니다신규, 윈 토토 기능이 지원하도록 수정될 수 있음반환 삽입그리고업데이트 반환 중(이는 후속 윈 토토에 전달되거나 특수 윈 토토에 전달되는 행 값에도 영향을 미칩니다.제외됨an 내의 별칭 참조삽입다음이 포함된 문충돌 시 업데이트를 하세요절). 에 대한삭제작업, 반환 값은 다음과 같아야 합니다오래된.

행 수준 윈 토토의 반환 값이 실행되었습니다.이후또는 명령문 수준 윈 토토가 실행됨이전또는이후항상 무시됩니다. null일 수도 있습니다. 그러나 이러한 유형의 윈 토토는 여전히 오류를 발생시켜 전체 작업을 중단할 수 있습니다.

예 41.3윈 토토 함수의 예를 보여줍니다.PL/pgSQL.

예제 41.3. 갑PL/pgSQL윈 토토 기능

이 예제 윈 토토는 행이 테이블에 삽입되거나 업데이트될 때마다 현재 사용자 이름과 시간이 행에 스탬프되도록 합니다. 그리고 직원의 이름이 주어지고 급여가 양수 값인지 확인합니다.

테이블 emp 생성(
    엠프 이름 텍스트,
    급여 정수,
    last_date 타임스탬프,
    last_user 텍스트
);

CREATE FUNCTION emp_stamp() $emp_stamp$로 윈 토토를 반환합니다.
    시작
        -- 사원명과 급여가 입력되었는지 확인하세요.
        NEW.empname이 NULL인 경우
            RAISE EXCEPTION 'empname은 null일 수 없습니다.';
        종료하면;
        NEW.salary가 NULL인 경우
            RAISE EXCEPTION '%는 null 급여를 가질 수 없습니다.', NEW.empname;
        종료하면;

        -- 비용을 지불해야 할 때 누가 우리를 위해 일합니까?
        NEW.salary < 0이면
            RAISE EXCEPTION '%는 음수 급여를 가질 수 없습니다.', NEW.empname;
        종료하면;

        -- 언제 급여를 변경했는지 기억해 보세요.
        NEW.last_date := 현재_타임스탬프;
        NEW.last_user := 현재_사용자;
        새로운 반품;
    끝;
$emp_stamp$ 언어 plpgsql;

emp를 삽입하거나 업데이트하기 전에 emp_stamp 윈 토토를 생성하세요.
    각 행에 대해 함수 실행 emp_stamp();

테이블에 변경 사항을 기록하는 또 다른 방법은 발생하는 각 삽입, 업데이트 또는 삭제에 대한 행을 보유하는 새 테이블을 생성하는 것입니다. 이 접근 방식은 테이블의 변경 사항을 감사하는 것으로 생각할 수 있습니다.예 41.4감사 윈 토토 기능의 예를 보여줍니다.PL/pgSQL.

예제 41.4. 갑PL/pgSQL감사를 위한 윈 토토 기능

이 예제 윈 토토는 행의 삽입, 업데이트 또는 삭제를 보장합니다.emp테이블은 다음에 기록(즉, 감사)됩니다.emp_audit테이블. 현재 시간과 사용자 이름이 수행된 작업 유형과 함께 행에 표시됩니다.

테이블 emp 생성(
    empname 텍스트는 NULL이 아닙니다.
    급여 정수
);

테이블 만들기 emp_audit(
    작업 char(1) NOT NULL,
    스탬프 타임스탬프 NOT NULL,
    사용자 ID 텍스트가 NULL이 아닙니다.
    empname 텍스트는 NULL이 아닙니다.
    급여 정수
);

함수 생성 또는 교체 process_emp_audit()는 $emp_audit$로 윈 토토를 반환합니다.
    시작
        --
        -- emp에서 수행된 작업을 반영하기 위해 emp_audit에 행을 생성합니다.
        -- 특수 변수 TG_OP를 사용하여 작업을 수행합니다.
        --
        IF (TG_OP = '삭제') THEN
            INSERT INTO emp_audit SELECT 'D', now(), current_user, OLD.*;
        ELSIF (TG_OP = 'UPDATE') 그런 다음
            INSERT INTO emp_audit SELECT 'U', now(), current_user, NEW.*;
        ELSIF (TG_OP = 'INSERT') 그런 다음
            INSERT INTO emp_audit SELECT 'I', now(), current_user, NEW.*;
        종료하면;
        NULL을 반환합니다. -- AFTER 윈 토토이므로 결과는 무시됩니다.
    끝;
$emp_audit$ LANGUAGE plpgsql;

윈 토토 생성 emp_audit
emp에서 삽입, 업데이트 또는 삭제 후
    각 행 실행 함수 process_emp_audit();

이전 예의 변형에서는 각 항목이 마지막으로 수정된 시기를 표시하기 위해 기본 테이블을 감사 테이블에 조인하는 뷰를 사용합니다. 이 접근 방식은 여전히 테이블 변경 사항에 대한 전체 감사 추적을 기록할 뿐만 아니라 감사 추적의 단순화된 보기도 제공하여 각 항목에 대한 감사 추적에서 파생된 마지막으로 수정된 타임스탬프만 표시합니다.예 41.5다음 보기에 대한 감사 윈 토토의 예를 보여줍니다.PL/pgSQL.

예제 41.5. 갑PL/pgSQL감사를 위한 윈 토토 기능 보기

이 예는 뷰에 대한 윈 토토를 사용하여 뷰를 업데이트 가능하게 만들고 뷰에 있는 행의 삽입, 업데이트 또는 삭제가 기록(즉, 감사)되도록 합니다.emp_audit테이블. 현재 시간과 사용자 이름이 수행된 작업 유형과 함께 기록되며 보기에는 각 행의 마지막 수정 시간이 표시됩니다.

테이블 emp 생성(
    empname 텍스트 기본 키,
    급여 정수
);

테이블 만들기 emp_audit(
    작업 char(1) NOT NULL,
    사용자 ID 텍스트가 NULL이 아닙니다.
    empname 텍스트는 NULL이 아닙니다.
    급여 정수,
    스탬프 타임스탬프 NOT NULL
);

emp_view AS 보기 만들기
    e.emp이름을 선택하세요.
           e.급여,
           max(ea.stamp) AS last_updated
      Emp e에서
      LEFT JOIN emp_audit ea ON ea.empname = e.empname
     1, 2로 그룹화;

함수 생성 또는 교체 update_emp_view()는 $$로 윈 토토를 반환합니다.
    시작
        --
        -- emp에서 필요한 작업을 수행하고 emp_audit에 행을 생성합니다.
        -- emp에 대한 변경 사항을 반영합니다.
        --
        IF (TG_OP = '삭제') THEN
            emp WHERE emp에서 삭제 empname = OLD.empname;
            찾을 수 없으면 NULL을 반환합니다. 종료하면;

            OLD.last_updated = 지금();
            INSERT INTO emp_audit VALUES('D', current_user, OLD.*);
            오래된 것을 반환하십시오;
        ELSIF (TG_OP = 'UPDATE') 그런 다음
            UPDATE emp SET 급여 = NEW.salary WHERE empname = OLD.empname;
            찾을 수 없으면 NULL을 반환합니다. 종료하면;

            NEW.last_updated = 지금();
            INSERT INTO emp_audit VALUES('U', current_user, NEW.*);
            새로운 반품;
        ELSIF (TG_OP = 'INSERT') 그런 다음
            INSERT INTO emp VALUES(NEW.empname, NEW.salary);

            NEW.last_updated = 지금();
            INSERT INTO emp_audit VALUES('I', current_user, NEW.*);
            새로운 반품;
        종료하면;
    끝;
$$ 언어 plpgsql;

윈 토토 생성 emp_audit
emp_view에 대한 삽입, 업데이트 또는 삭제 대신
    각 행에 대해 함수 실행 update_emp_view();

윈 토토의 용도 중 하나는 다른 테이블의 요약 테이블을 유지하는 것입니다. 결과 요약은 특정 쿼리에 대해 원본 테이블 대신 사용할 수 있으며 종종 실행 시간이 크게 단축됩니다. 이 기술은 측정되거나 관찰된 데이터 테이블(사실 테이블이라고 함)이 매우 클 수 있는 데이터 웨어하우징에서 일반적으로 사용됩니다.예 41.6윈 토토 함수의 예를 보여줍니다.PL/pgSQL데이터 웨어하우스의 팩트 테이블에 대한 요약 테이블을 유지 관리합니다.

예제 41.6. 갑PL/pgSQL요약 테이블 유지를 위한 윈 토토 기능

여기에 자세히 설명된 스키마는 부분적으로 다음을 기반으로 합니다.식료품점예제데이터 웨어하우스 툴킷작성자: 랄프 킴볼.

--
-- 기본 테이블 - 시간 차원 및 판매 사실.
--
CREATE TABLE time_dimension(
    time_key 정수는 NULL이 아닙니다.
    day_of_week 정수는 NULL이 아닙니다.
    day_of_month 정수는 NULL이 아닙니다.
    월 정수는 NULL이 아닙니다.
    분기 정수는 NULL이 아닙니다.
    연도 정수 NULL이 아님
);
고유 인덱스 생성 time_dimension_key ON time_dimension(time_key);

CREATE TABLE sales_fact (
    time_key 정수는 NULL이 아닙니다.
    product_key 정수는 NULL이 아닙니다.
    store_key 정수는 NULL이 아닙니다.
    amount_sold 숫자(12,2) NOT NULL,
    units_sold 정수는 NULL이 아닙니다.
    amount_cost 숫자(12,2) NOT NULL
);
CREATE INDEX sales_fact_time ON sales_fact(time_key);

--
-- 요약 테이블 - 시간별 판매.
--
CREATE TABLE sales_summary_bytime(
    time_key 정수는 NULL이 아닙니다.
    amount_sold 숫자(15,2) NOT NULL,
    units_sold 숫자(12) NOT NULL,
    amount_cost 숫자(15,2) NULL이 아님
);
고유 인덱스 생성 sales_summary_bytime_key ON sales_summary_bytime(time_key);

--
-- UPDATE, INSERT, DELETE 시 요약된 열을 수정하는 함수 및 윈 토토입니다.
--
함수 생성 또는 교체 maint_sales_summary_bytime() 반환 윈 토토
AS $maint_sales_summary_bytime$
    선언
        delta_time_key 정수;
        delta_amount_sold 숫자(15,2);
        delta_units_sold 숫자(12);
        delta_amount_cost 숫자(15,2);
    시작

        -- 증가/감소 금액을 계산합니다.
        IF (TG_OP = '삭제') THEN

            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) THEN
                RAISE EXCEPTION 'time_key 업데이트: % - % 허용되지 않음',
                                                      OLD.time_key, NEW.time_key;
            종료하면;

            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;

        종료하면;

        -- 새 값으로 요약 행을 삽입하거나 업데이트합니다.
        <<삽입_업데이트
        루프
            업데이트 sales_summary_bytime
                SET 판매_금액 = 판매_금액 + 델타_판매_금액,
                    단위_판매 = 단위_판매 + 델타_단위_판매,
                    amount_cost = amount_cost + delta_amount_cost
                여기서 time_key = delta_time_key;

            insert_update가 발견되면 종료하세요.

            시작
                sales_summary_bytime에 삽입(
                            시간_키,
                            금액_판매,
                            단위_판매,
                            금액_비용)
                    값(
                            delta_time_key,
                            delta_amount_sold,
                            delta_units_sold,
                            delta_amount_cost
                           );

                종료 insert_update;

            예외
                WHEN UNIQUE_VIOLATION THEN
                    -- 아무것도 하지 마세요
            끝;
        END LOOP insert_update;

        NULL을 반환합니다.

    끝;
$maint_sales_summary_bytime$ LANGUAGE plpgsql;

생성 윈 토토 maint_sales_summary_bytime
sales_fact에 대한 삽입, 업데이트 또는 삭제 후
    각 행에 대해 함수 실행 maint_sales_summary_bytime();

sales_fact VALUES(1,1,1,10,3,15)에 삽입;
sales_fact VALUES(1,2,1,20,5,35)에 삽입;
sales_fact VALUES(2,2,1,40,15,135)에 삽입;
sales_fact VALUES(2,3,1,10,1,13)에 삽입;
SELECT * FROM sales_summary_bytime;
product_key = 1인 sales_fact에서 삭제합니다.
SELECT * FROM sales_summary_bytime;
UPDATE sales_fact SET 유닛_판매 = 유닛_판매 * 2;
SELECT * FROM sales_summary_bytime;

이후윈 토토도 사용할 수 있습니다전환 테이블윈 토토 문에 의해 변경된 전체 행 집합을 검사합니다.윈 토토 생성명령은 하나 또는 두 개의 전환 테이블에 이름을 할당하며, 그러면 함수는 마치 읽기 전용 임시 테이블인 것처럼 해당 이름을 참조할 수 있습니다.예 41.7예를 보여줍니다.

예 41.7. 전환 테이블을 사용한 감사

이 예는 다음과 동일한 결과를 생성합니다.예 41.4, 그러나 모든 행에 대해 실행되는 윈 토토를 사용하는 대신 전환 테이블에서 관련 정보를 수집한 후 문당 한 번 실행되는 윈 토토를 사용합니다. 이는 호출 문이 많은 행을 수정한 경우 행 윈 토토 접근 방식보다 훨씬 더 빠를 수 있습니다. 각 종류의 이벤트에 대해 별도의 윈 토토 선언을 만들어야 한다는 점에 유의하세요.참조 중절은 사례마다 달라야 합니다. 그러나 이것이 우리가 선택하는 경우 단일 윈 토토 기능을 사용하는 것을 막지는 않습니다. (실제로는 세 가지 별도의 함수를 사용하고 런타임 테스트를 피하는 것이 더 나을 수 있습니다.TG_OP.)

테이블 emp 생성(
    empname 텍스트는 NULL이 아닙니다.
    급여 정수
);

테이블 만들기 emp_audit(
    작업 char(1) NOT NULL,
    스탬프 타임스탬프 NOT NULL,
    사용자 ID 텍스트가 NULL이 아닙니다.
    empname 텍스트는 NULL이 아닙니다.
    급여 정수
);

함수 생성 또는 교체 process_emp_audit()는 $emp_audit$로 윈 토토를 반환합니다.
    시작
        --
        -- emp에서 수행된 작업을 반영하기 위해 emp_audit에 행을 생성합니다.
        -- 특수 변수 TG_OP를 사용하여 작업을 수행합니다.
        --
        IF (TG_OP = '삭제') THEN
            emp_audit에 삽입
                SELECT 'D', now(), current_user, o.* FROM old_table o;
        ELSIF (TG_OP = 'UPDATE') 그런 다음
            emp_audit에 삽입
                SELECT 'U', now(), current_user, n.* FROM new_table n;
        ELSIF (TG_OP = 'INSERT') 그런 다음
            emp_audit에 삽입
                SELECT 'I', now(), current_user, n.* FROM new_table n;
        종료하면;
        NULL을 반환합니다. -- AFTER 윈 토토이므로 결과는 무시됩니다.
    끝;
$emp_audit$ LANGUAGE plpgsql;

윈 토토 생성 emp_audit_ins
    emp에 삽입한 후
    새 테이블을 new_table로 참조
    각 명령문 실행 함수에 대해 process_emp_audit();
윈 토토 생성 emp_audit_upd
    emp 업데이트 후
    이전 테이블을 old_table로 참조 새 테이블을 new_table로 참조
    각 명령문 실행 함수에 대해 process_emp_audit();
윈 토토 생성 emp_audit_del
    Emp에서 삭제 후
    old_table로 이전 테이블 참조
    각 명령문 실행 함수에 대해 process_emp_audit();

41.10.2. 이벤트 윈 토토#

PL/pgSQL정의하는 데 사용할 수 있습니다.43토토 사이트 추천15. PostgreSQL이벤트 윈 토토로 호출되는 함수는 인수가 없고 반환 유형이 다음과 같은 함수로 선언되어야 합니다.event_trigger.

언제PL/pgSQL함수가 이벤트 윈 토토로 호출되면 여러 특수 변수가 최상위 블록에 자동으로 생성됩니다. 그들은:

TG_EVENT 텍스트 #

윈 토토가 실행되는 이벤트입니다.

TG_TAG 텍스트 #

윈 토토가 실행되는 명령 태그.

예 41.8이벤트 윈 토토 기능의 예를 보여줍니다.PL/pgSQL.

예 41.8. 갑PL/pgSQL이벤트 윈 토토 기능

이 예시 윈 토토는 단순히 a공지지원되는 명령이 실행될 때마다 메시지가 표시됩니다.

함수 생성 또는 교체 snitch()는 event_trigger를 $$로 반환합니다.
시작
    알림 올리기 '밀고자: % %', tg_event, tg_tag;
끝;
$$ 언어 plpgsql;

ddl_command_start에서 이벤트 윈 토토 스니치 생성 함수 실행 snitch();

수정 사항 제출

문서에 올바르지 않은 내용이 있으면 일치하지 않습니다. 특정 기능에 대한 경험이 있거나 추가 설명이 필요한 경우 이용해주세요이 양식문서 문제를 보고합니다.