?
このドキュメントでは、 php中國(guó)語(yǔ)ネットマニュアル リリース
本章描述觸發(fā)器函數(shù)的低層細(xì)節(jié)。只有當(dāng)你用 C 書(shū)寫(xiě)觸發(fā)器函數(shù)的時(shí)候才需要這些信息。 如果你用某種高級(jí)語(yǔ)言寫(xiě)觸發(fā)器,那么系統(tǒng)就會(huì)為你處理這些細(xì)節(jié)。 在大多數(shù)情況下,你在書(shū)寫(xiě)自己的 C 觸發(fā)器之前應(yīng)該考慮使用過(guò)程語(yǔ)言。 每種過(guò)程語(yǔ)言的文檔里面都有關(guān)于如何用該語(yǔ)言書(shū)寫(xiě)觸發(fā)器的解釋。
觸發(fā)器函數(shù)必須使用"version 1"的函數(shù)管理器接口
當(dāng)一個(gè)函數(shù)被觸發(fā)器管理器調(diào)用時(shí),它不會(huì)收到任何普通參數(shù),而是收到一個(gè) 指向TriggerData結(jié)構(gòu)的"context"指針。C 函數(shù)可以通過(guò)執(zhí)行下面的宏來(lái)檢查 它們是否是從觸發(fā)器管理器調(diào)用的,或者不是:
CALLED_AS_TRIGGER(fcinfo)
which expands to:
((fcinfo)->context != NULL && IsA((fcinfo)->context, TriggerData))
如果此宏返回真(TRUE), 則可以安全地把 fcinfo->context轉(zhuǎn)換成TriggerData*類(lèi)型, 然后使用這個(gè)指向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; Buffer tg_trigtuplebuf; Buffer tg_newtuplebuf; } TriggerData;
這些成員的定義如下:
通常是T_TriggerData.
描述調(diào)用函數(shù)的事件。你可以用下面的宏檢查tg_event:
如果觸發(fā)器是在操作前觸發(fā),返回真
如果觸發(fā)器是在操作后觸發(fā),返回真。
如果觸發(fā)器是行級(jí)別事件觸發(fā),返回真。
如果觸發(fā)器是語(yǔ)句級(jí)別事件觸發(fā),返回真。
如果觸發(fā)器是由INSERT觸發(fā),返回真。
如果觸發(fā)器是由UPDATE觸發(fā),返回真
如果觸發(fā)器是由DELETE觸發(fā),返回真
如果TRUNCATE命令觸發(fā)了觸發(fā)器,那么返回真。
是一個(gè)指向描述被觸發(fā)的關(guān)系的結(jié)構(gòu)的指針。請(qǐng)參考utils/rel.h獲取關(guān)于此結(jié)構(gòu)的 詳細(xì)信息。最讓人感興趣的事情是tg_relation->rd_att(關(guān)系行的描述) 和 tg_relation->rd_rel->relname(關(guān)系名。這個(gè)變量的類(lèi)型不是char*而是NameData。 如果你需要一份名字的拷貝,用SPI_getrelname(tg_relation)獲取char* )。
是一個(gè)指向被觸發(fā)觸發(fā)器的行的指針。這是一個(gè)正在被插入INSERT或DELETE的行。 如果是INSERT或DELETE觸發(fā)觸發(fā)器,并且如果你不想用另一條行覆蓋 此行(INSERT)或忽略操作(INSERT),那么這就是你將返回給執(zhí)行者的東西
如果是UPDATE觸發(fā)的觸發(fā)器,則是一個(gè)指向新版本的行的指針, 如果是INSERT或DELETE, 則是NULL。如果事件是UPDATE 并且你不想用另一條行替換這條行或忽略操作的話(huà),這就是你將返回給執(zhí)行者的東西。
是一個(gè)指向結(jié)構(gòu)Trigger的指針,該結(jié)構(gòu)在utils/rel.h里定義:
typedef struct Trigger { Oid tgoid; char *tgname; Oid tgfoid; int16 tgtype; bool tgenabled; bool tgisinternal; Oid tgconstrrelid; Oid tgconstrindid; Oid tgconstraint; bool tgdeferrable; bool tginitdeferred; int16 tgnargs; int16 tgnattr; int16 *tgattr; char **tgargs; char *tgqual; } Trigger;
tgname是觸發(fā)器的名稱(chēng),tgnargs是在tgargs里參數(shù)的數(shù)量, tgargs是一個(gè)聲明在CREATE TRIGGER語(yǔ)句中的指針數(shù)組。 其它成員只在內(nèi)部使用。
如果沒(méi)有這樣的元組或者沒(méi)有存儲(chǔ)在磁盤(pán)緩沖區(qū)里, 則是包含tg_trigtuple或者InvalidBuffer的緩沖區(qū)。
如果沒(méi)有這樣的元組或者它并未存儲(chǔ)在磁盤(pán)緩沖區(qū)里, 那么就是包含tg_newtuple或者InvalidBuffer的緩沖區(qū)
一個(gè)觸發(fā)器函數(shù)必須返回一個(gè)HeapTuple指針或者一個(gè)NULL指針(不是 SQL 的 NULL 值, 也就是說(shuō)不要設(shè)置 isNull為真)。請(qǐng)注意如果你不想修改正在被操作的行, 那么要根據(jù)情況返回tg_trigtuple或tg_newtuple。