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

39.9. 트리거 절차

PL/pgSQL다음에 사용할 수 있습니다. 트리거 절차를 정의합니다. 트리거 프로시저는 다음을 사용하여 생성됩니다.함수 생성명령, 선언 인수가 없고 반환 유형이인 함수입니다.트리거. 기능은 다음과 같아야합니다. 수신할 것으로 예상되는 경우에도 인수 없이 선언됩니다. 에 지정된 인수트리거 생성— 트리거 인수는 다음을 통해 전달됩니다.TG_ARGV, 아래 설명대로.

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

신규

메이저 토토 사이트터 유형기록; 가변 보유 에 대한 새 메이저 토토 사이트터베이스 행삽입/업메이저 토토 사이트트행 수준 트리거의 작업. 이 변수는NULL문 수준 트리거에서 그리고삭제작업.

오래된

메이저 토토 사이트터 유형기록; 가변 보유 에 대한 이전 데이터베이스 행업메이저 토토 사이트트/삭제행 수준 트리거의 작업. 이 변수는NULL문 수준 트리거에서 그리고삽입작업.

TG_NAME

메이저 토토 사이트터 유형이름; 그 변수 실제로 실행된 트리거의 이름을 포함합니다.

TG_WHEN

메이저 토토 사이트터 유형텍스트; 문자열이전, 이후또는대신 OF, 트리거 정의에 따라 다름.

TG_LEVEL

메이저 토토 사이트터 유형텍스트; 문자열 중 하나ROW또는진술문트리거에 따라 다름 정의.

TG_OP

메이저 토토 사이트터 유형텍스트; 문자열삽입, 업메이저 토토 사이트트, 삭제또는잘라내기무엇을 말하는가 작업이 트리거가 실행되었습니다.

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또는 정확히 다음을 갖는 레코드/행 값 트리거가 실행된 테이블의 구조입니다.

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

대신트리거(항상 행 수준 트리거이며 뷰에서만 사용할 수 있음) 업메이저 토토 사이트트를 수행하지 않았음을 알리는 null입니다. 이 행에 대한 나머지 작업은 건너뛰어야 합니다(예: 후속 트리거는 실행되지 않으며 행은 계산되지 않습니다. 주변에 대한 행의 영향을 받는 상태삽입/업메이저 토토 사이트트/삭제). 그렇지 않으면 null이 아닌 값은 다음과 같아야 합니다. 반환되어 트리거가 요청된 작업을 수행했음을 알립니다. 운영. 에 대한삽입그리고업메이저 토토 사이트트작업, 반환 값은 다음과 같아야 합니다신규, 트리거 함수는 지원하도록 수정반환 삽입그리고업메이저 토토 사이트트 반환 중(이것은 또한 영향을 미칩니다 후속 트리거에 전달된 행 값) 에 대한삭제작업, 반환 값은 다음과 같아야 합니다.오래된.

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

예 39-3트리거 절차의 예를 보여줍니다.PL/pgSQL.

예 39-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();

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

예 39-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(), 사용자, OLD.*;
            오래된 것을 반환하십시오;
        ELSIF (TG_OP = 'UPDATE') 그런 다음
            INSERT INTO emp_audit SELECT 'U', now(), user, NEW.*;
            새로운 반품;
        ELSIF (TG_OP = 'INSERT') 그런 다음
            INSERT INTO emp_audit SELECT 'I', now(), user, NEW.*;
            새로운 반품;
        종료하면;
        NULL을 반환합니다. -- AFTER 트리거이므로 결과는 무시됩니다.
    끝;
$emp_audit$ LANGUAGE plpgsql;

트리거 생성 emp_audit
emp에서 삽입, 업메이저 토토 사이트트 또는 삭제 후
    각 행 실행 절차 process_emp_audit();

이전 예의 변형은 각 항목이 마지막이었던 시기를 표시하기 위해 기본 테이블을 감사 테이블로 변경 수정되었습니다. 이 접근 방식은 여전히 전체 감사 추적을 기록합니다. 테이블이 변경될 뿐만 아니라 테이블에 대한 단순화된 보기도 제공됩니다. 마지막으로 수정된 타임스탬프만 표시하는 감사 추적 각 항목에 대한 감사 추적에서.예 39-5다음 보기에 대한 감사 트리거의 예를 보여줍니다.PL/pgSQL.

예 39-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', 사용자, OLD.*);
            오래된 것을 반환하십시오;
        ELSIF (TG_OP = 'UPDATE') 그런 다음
            UPDATE emp SET 급여 = NEW.salary WHERE empname = OLD.empname;
            찾을 수 없으면 NULL을 반환합니다. 종료하면;

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

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

트리거 생성 emp_audit
emp_view에 대한 삽입, 업메이저 토토 사이트트 또는 삭제 대신
    각 행 실행 절차 update_emp_view();

트리거의 한 가지 용도는 다른 트리거의 요약 테이블을 유지하는 것입니다 테이블. 결과 요약은 원본 대신 사용할 수 있습니다. 특정 쿼리에 대한 테이블 - 실행 시간이 크게 단축되는 경우가 많습니다. 이 기술은 일반적으로 데이터 웨어하우징에서 사용됩니다. 측정되거나 관찰된 데이터 테이블(사실 테이블이라고 함)은 엄청나게 크다.예 39-6트리거 절차의 예를 보여줍니다.PL/pgSQL다음에 대한 요약 테이블을 유지 관리합니다. 데이터 웨어하우스의 팩트 테이블입니다.

예 39-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;