W3Cschool
恭喜您成為首批注冊用戶
獲得88經(jīng)驗值獎勵
這一節(jié)描述了一個觸發(fā)器函數(shù)的接口的低層細節(jié)。只有用 C 編寫觸發(fā)器函數(shù)時才需要這些信息。如果你使用一種更高層的語言,那么這些細節(jié)就不需要你來處理。在大部分情況下,你應(yīng)該優(yōu)先考慮使用一種過程語言。每一種過程語言的文檔闡述了如何使用那種語言編寫一個觸發(fā)器。
觸發(fā)器函數(shù)必須使用“版本 1”函數(shù)管理器接口。
當(dāng)一個函數(shù)被觸發(fā)器管理器調(diào)用時,不會給它傳遞任何常規(guī)的參數(shù),但是會有一個“context”指針傳遞給它,該指針指向一個TriggerData
結(jié)構(gòu)。C 函數(shù)可以通過執(zhí)行一個宏來檢查它們是否是從觸發(fā)器管理器被調(diào)用:
CALLED_AS_TRIGGER(fcinfo)
它會展開成為:
((fcinfo)->context != NULL && IsA((fcinfo)->context, TriggerData))
如果這返回真,那么將fcinfo->context
造型成類型TriggerData *
并且利用所指向的TriggerData
結(jié)構(gòu)就是安全的。該函數(shù)不能修改該TriggerData
結(jié)構(gòu)或者它指向的任何數(shù)據(jù)。
struct TriggerData
被定義在commands/trigger.h
中:
typedef struct TriggerData
{
NodeTag type;
TriggerEvent tg_event;
Relation tg_relation;
HeapTuple tg_trigtuple;
HeapTuple tg_newtuple;
Trigger *tg_trigger;
TupleTableSlot *tg_trigslot;
TupleTableSlot *tg_newslot;
Tuplestorestate *tg_oldtable;
Tuplestorestate *tg_newtable;
const Bitmapset *tg_updatedcols;
} TriggerData;
其中的成員被定義如下:
type
總是T_TriggerData
.
tg_event
描述該函數(shù)是為什么事件被調(diào)用的。你可以使用下列宏來檢查tg_event
:
TRIGGER_FIRED_BEFORE(tg_event)
如果該觸發(fā)器在操作前被引發(fā)則返回真。
TRIGGER_FIRED_AFTER(tg_event)
如果該觸發(fā)器在操作后被引發(fā)則返回真。
TRIGGER_FIRED_INSTEAD(tg_event)
如果該觸發(fā)器被引發(fā)替代操作則返回真。
TRIGGER_FIRED_FOR_ROW(tg_event)
如果該觸發(fā)器為一個行級事件而引發(fā)則返回真。
TRIGGER_FIRED_FOR_STATEMENT(tg_event)
如果該觸發(fā)器為一個語句級事件而引發(fā)則返回真。
TRIGGER_FIRED_BY_INSERT(tg_event)
如果該觸發(fā)器由一個INSERT
命令引發(fā)則返回真。
TRIGGER_FIRED_BY_UPDATE(tg_event)
如果該觸發(fā)器由一個UPDATE
命令引發(fā)則返回真。
TRIGGER_FIRED_BY_DELETE(tg_event)
如果該觸發(fā)器由一個DELETE
命令引發(fā)則返回真。
TRIGGER_FIRED_BY_TRUNCATE(tg_event)
如果該觸發(fā)器由一個TRUNCATE
命令引發(fā)則返回真。
tg_relation
一個結(jié)構(gòu)指針,該結(jié)構(gòu)描述該觸發(fā)器為其引發(fā)的關(guān)系。關(guān)于這個結(jié)構(gòu)的細節(jié)請參考utils/rel.h
。最有趣的東西是tg_relation->rd_att
(該關(guān)系元組的描述符)和tg_relation->rd_rel->relname
(關(guān)系名稱,該類型不是char*
而是
NameData
。如果你需要該名稱的一個拷貝,可使用SPI_getrelname(tg_relation)
來得到一個char*
)。
tg_trigtuple
一個該觸發(fā)器為其引發(fā)的行的指針。這是被插入、更新或刪除的行。如果這個觸發(fā)器是為一個INSERT
或DELETE
而引發(fā),在你不想把該行替換成另一行(在INSERT
的情況中)或不想跳過該操作時你應(yīng)該從該函數(shù)中返回它。 對于外部表上的觸發(fā)器,此中的系統(tǒng)列值未被指定。
tg_newtuple
如果該觸發(fā)器為一個UPDATE
而引發(fā),則是一個指向該行新版本的指針。如果是為一個INSERT
或DELETE
而引發(fā),則是NULL
。如果事件是一個UPDATE
并且你并不想用一個不同的行替換這個行或者不想跳過該操作時,你必須從函數(shù)中返回它。對于外部表上的觸發(fā)器,此中的系統(tǒng)列值未被指定。
tg_trigger
一個指向類型為Trigger
的結(jié)構(gòu)的指針,定義在utils/reltrigger.h
中:
typedef struct Trigger
{
Oid tgoid;
char *tgname;
Oid tgfoid;
int16 tgtype;
char tgenabled;
bool tgisinternal;
Oid tgconstrrelid;
Oid tgconstrindid;
Oid tgconstraint;
bool tgdeferrable;
bool tginitdeferred;
int16 tgnargs;
int16 tgnattr;
int16 *tgattr;
char **tgargs;
char *tgqual;
char *tgoldtable;
char *tgnewtable;
} Trigger;
其中tgname
是該觸發(fā)器的名稱,tgnargs
是tgargs
中參數(shù)的數(shù)量,而tgargs
是一個指向CREATE TRIGGER
語句中指定的參數(shù)的指針數(shù)組。其他成員只用于內(nèi)部用途。
tg_trigtuplebuf
包含tg_trigtuple
的插槽?;蛘咭粋€NULL
指針,如果沒有這樣的元組的話。
tg_newtuplebuf
包含tg_trigtuple
的插槽?;蛘咭粋€NULL
指針,如果沒有這樣的元組的話。
tg_oldtable
一個指向Tuplestorestate
類型的結(jié)構(gòu)的指針,該結(jié)構(gòu)包含格式由tg_relation
指定的零行或者多行。如果沒有OLD TABLE
傳遞關(guān)系,則為NULL
指針。
tg_newtable
一個指向Tuplestorestate
類型的結(jié)構(gòu)的指針,該結(jié)構(gòu)包含格式由tg_relation
指定的零行或者多行。如果沒有NEW TABLE
傳遞關(guān)系,則為NULL
指針。
tg_updatedcols
對于 UPDATE
觸發(fā)器,位圖集指示由觸發(fā)命令更新的列。 通用觸發(fā)器函數(shù)可以使用它來優(yōu)化操作,而不必處理未更改的列。
例如,要確定屬性編號為 attnum
(基于 1)的列是否是此位圖集的成員,請調(diào)用 bms_is_member(attnum -
FirstLowInvalidHeapAttributeNumber,
trigdata->tg_updatedcols))
。
對于UPDATE
觸發(fā)器以外的觸發(fā)器,這將是NULL
。
為了允許通過SPI發(fā)出的查詢引用傳遞表,請參考SPI_register_trigger_data。
一個觸發(fā)器函數(shù)必須返回一個HeapTuple
指針或一個NULL
指針(不是一個 SQL 空值,也就是不會設(shè)置isNull
為真)。如果你不希望修改正在被操作的行,要小心地根據(jù)情況返回tg_trigtuple
或
tg_newtuple
。
Copyright©2021 w3cschool編程獅|閩ICP備15016281號-3|閩公網(wǎng)安備35020302033924號
違法和不良信息舉報電話:173-0602-2364|舉報郵箱:jubao@eeedong.com
掃描二維碼
下載編程獅App
編程獅公眾號
聯(lián)系方式:
更多建議: