2025년 9월 25일:토토 커뮤니티 : 토토
이 문서는 지원되지 않는 PostgreSQL 버전에 대한 것입니다.
당신은 다음과 같은 페이지를 보고 싶을 수도 있습니다.현재버전 또는 위에 나열된 다른 지원 버전 중 하나를 사용하세요.

20.4. 예

다음에 더 복잡한 예가 있습니다.src/test/regress/regress.c그리고기여/spi.

다음은 트리거 사용법의 매우 간단한 예입니다. 함수 삼각 트리거된 관계의 튜플 수를 보고합니다. 쿼리가 x에 NULL을 삽입하려고 시도하면 작업을 건너뜁니다. (즉, NOT NULL 제약 조건으로 작동하지만 중단하지는 않습니다. 거래).

#include "executor/spi.h" /* SPI로 작업하는 데 필요한 것입니다 */
#include "commands/trigger.h" /* -"- 및 트리거 */

extern 데이텀 trigf(PG_FUNCTION_ARGS);

PG_FUNCTION_INFO_V1(trigf);

데이텀
삼각(PG_FUNCTION_ARGS)

        TriggerData *trigdata = (TriggerData *) fcinfo-context;
        TupleDesc tupdesc;
        HeapTuple retuple;
        문자 *언제;
        부울 체크널 = 거짓;
        bool은 null입니다.
        int ret, i;

        /* trigdata가 내가 기대하는 것을 가리키고 있는지 확인하세요 */
        if (!CALLED_AS_TRIGGER(fcinfo))
                elog(ERROR, "trigf: 트리거 관리자에 의해 실행되지 않았습니다.");

        /* Executor로 돌아갈 튜플 */
        if (TRIGGER_FIRED_BY_UPDATE(trigdata-tg_event))
                rettuple = trigdata-tg_newtuple;
        그렇지 않으면
                rettuple = trigdata-tg_trigtuple;

        /* NULL을 확인합니까? */
        if (!TRIGGER_FIRED_BY_DELETE(trigdata-tg_event) &&
                TRIGGER_FIRED_BEFORE(trigdata-tg_event))
                체크널 = 참;

        if (TRIGGER_FIRED_BEFORE(trigdata-tg_event))
                when = "이전";
        그렇지 않으면
                언제 = "이후";

        tupdesc = trigdata-tg_relation-rd_att;

        /* SPI 관리자에 연결 */
        if ((ret = SPI_connect()) < 0)
                elog(NOTICE, "trigf(%s 실행): SPI_connect가 %d을(를) 반환했습니다.", when, ret);

        /* 관계에 있는 튜플의 수를 구합니다 */
        ret = SPI_exec("SELECT count(*) FROM ttest", 0);

        만약 (ret < 0)
                elog(NOTICE, "trigf(%s 실행): SPI_exec가 %d을(를) 반환했습니다.", when, ret);

        /* count(*)는 PG 7.2부터 int8을 반환하므로 변환에 주의하세요 */
        i = (int) DatumGetInt64(SPI_getbinval(SPI_tuptable-vals[0],
                                              SPI_tuptable-tupdesc,
                                              1,
                                              &isnull));

        elog(알림, "trigf(%s 실행됨): ttest에 %d개의 튜플이 있습니다.", when, i);

        SPI_finish();

        if(체크널)

                (공허) SPI_getbinval(rettuple, tupdesc, 1, &isnull);
                만약 (isnull)
                        리튜플 = NULL;

        return PointerGetDatum(retuple);

이제 트리거 함수를 컴파일하고 생성하십시오:

CREATE FUNCTION trigf()는 불투명한 값을 반환합니다. 
'...path_to_so' LANGUAGE 'C';

테이블 생성 토토 캔 (x int4);
vac= ttest에서 삽입, 업데이트 또는 삭제하기 전에 트리거를 생성하세요. 
각 행 실행 절차 trigf();
만들기
vac= ttest에서 삽입, 업데이트 또는 삭제 후 트리거 tafter 생성 
각 행 실행 절차 trigf();
만들기
vac= ttest 값에 삽입(NULL);
주의 사항:trigf(이전에 실행됨): ttest에는 0개의 튜플이 있습니다.
삽입 0 0

-- 삽입을 건너뛰고 AFTER 트리거가 실행되지 않습니다.

vac= SELECT * FROM ttest;
엑스
-
(0행)

vac= 테스트 값에 삽입(1);
주의 사항:trigf(이전에 실행됨): ttest에는 0개의 튜플이 있습니다.
주의 사항:trigf( 이후에 실행됨): ttest에는 1개의 튜플이 있습니다.
                                       ^^^^^^^^
                             가시성에 관해 우리가 말한 것을 기억하십시오.
삽입 167793 1
vac= SELECT * FROM ttest;
엑스
-
1
(1줄)

vac= ttest에 삽입 SELECT x * 2 FROM ttest;
주의 사항:trigf(이전에 실행됨): ttest에는 1개의 튜플이 있습니다.
주의 사항:trigf(다음에 실행됨): ttest에는 2개의 튜플이 있습니다.
                                       ^^^^^^^^
                             가시성에 관해 우리가 말한 것을 기억하십시오.
삽입 167794 1
vac= SELECT * FROM ttest;
엑스
-
1
2
(2열)

vac= 업데이트 ttest SET x = null WHERE x = 2;
주의 사항:trigf(이전에 실행됨): ttest에는 2개의 튜플이 있습니다.
업데이트 0
vac= 업데이트 ttest SET x = 4 WHERE x = 2;
주의 사항:trigf(이전에 실행됨): ttest에는 2개의 튜플이 있습니다.
주의 사항:trigf(다음에 실행됨): ttest에는 2개의 튜플이 있습니다.
업데이트 1
vac= SELECT * FROM ttest;
엑스
-
1
4
(2열)

vac= ttest에서 삭제;
주의 사항:trigf(이전에 실행됨): ttest에는 2개의 튜플이 있습니다.
주의 사항:trigf( 이후에 실행됨): ttest에는 1개의 튜플이 있습니다.
주의 사항:trigf(이전에 실행됨): ttest에는 1개의 튜플이 있습니다.
주의사항:trigf(다음에 실행됨): ttest에 0개의 튜플이 있습니다.
                                       ^^^^^^^^
                             가시성에 관해 우리가 말한 것을 기억하십시오.
2 삭제
vac= SELECT * FROM ttest;
엑스
-
(0행)