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

41.9. 토토 사이트 절차

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

41.9.1. 데이터 변경 시 토토 사이트

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

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

신규

데이터 유형기록; 에 대한 새 데이터베이스 행을 보유하는 변수삽입/업데이트행 수준 토토 사이트의 작업. 이 변수는 명령문 수준 토토 사이트 및 for에서 할당되지 않습니다.삭제작업.

오래된

데이터 유형기록; 이전 데이터베이스 행을 보유하는 변수업데이트/삭제행 수준 토토 사이트의 작업. 이 변수는 명령문 수준 토토 사이트 및 for에서 할당되지 않습니다.삽입작업.

TG_NAME

데이터 유형이름; 실제로 실행된 토토 사이트의 이름이 포함된 변수입니다.

TG_WHEN

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

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임삭제토토 사이트이므로 이를 반환하는 것은 일반적으로 합리적이지 않습니다. 의 일반적인 관용어삭제토토 사이트가 반환됩니다.오래된.

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

행 수준 토토 사이트의 반환 값이 실행되었습니다.이후또는 명령문 수준 토토 사이트가 실행됨이전또는이후항상 무시됩니다. 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(), 사용자, 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();

이전 예의 변형에서는 기본 테이블을 감사 테이블에 조인하는 뷰를 사용하여 각 항목이 마지막으로 수정된 시기를 표시합니다. 이 접근 방식은 여전히 테이블 변경 사항에 대한 전체 감사 추적을 기록할 뿐만 아니라 감사 추적의 단순화된 보기도 제공하여 각 항목에 대한 감사 추적에서 파생된 마지막으로 수정된 타임스탬프만 표시합니다.예 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', 사용자, 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();

토토 사이트의 용도 중 하나는 다른 테이블의 요약 테이블을 유지하는 것입니다. 결과 요약은 특정 쿼리에 대해 원본 테이블 대신 사용할 수 있으며 종종 실행 시간이 크게 단축됩니다. 이 기술은 측정되거나 관찰된 데이터 테이블(사실 테이블이라고 함)이 매우 클 수 있는 데이터 웨어하우징에서 일반적으로 사용됩니다.예 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.9.2. 이벤트 토토 사이트

PL/pgSQL정의하는 데 사용할 수 있습니다.PostgreSQL : 문서 : 9.6 : 이벤트 메이저 토토 사이트. 포스트그레SQL이벤트 토토 사이트로 호출될 프로시저는 인수가 없고 반환 유형이 다음과 같은 함수로 선언되어야 합니다.event_trigger.

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

TG_EVENT

데이터 유형텍스트; 토토 사이트가 실행되는 이벤트를 나타내는 문자열입니다.

TG_TAG

데이터 유형텍스트; 토토 사이트가 실행되는 명령 태그가 포함된 변수입니다.

예 41-7이벤트 토토 사이트 절차의 예를 보여줍니다.PL/pgSQL.

예 41-7. 갑PL/pgSQL이벤트 토토 사이트 절차

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

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

ddl_command_start 실행 절차 snitch()에서 이벤트 토토 사이트 생성 snitch();