# 39.3.用C语言编写触发器函数
本节介绍触发函数接口的低级细节。只有在用C编写触发器函数时才需要这些信息。如果您使用的是更高级的语言,那么这些细节将为您处理。在大多数情况下,在编写C.的触发器之前,您应该考虑使用过程语言。每个过程语言的文档解释了如何在该语言中编写触发器。
触发器功能必须使用“版本1”功能管理器界面。
触发器管理器调用函数时,不会向其传递任何常规参数,但会向其传递一个指向触发数据
结构C函数可以通过执行宏来检查它们是否是从触发器管理器调用的:
CALLED_AS_TRIGGER(fcinfo)
扩展到:
((fcinfo)->context != NULL && IsA((fcinfo)->context, TriggerData))
如果返回true,则可以安全地进行强制转换fcinfo->context
打字触发数据*
并利用指向触发数据
结构函数必须不改变触发数据
结构或它指向的任何数据。
结构触发器数据
定义在命令/触发器。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;
成员定义如下:
类型
总是触发数据
.
tg_事件
描述为其调用函数的事件。您可以使用以下宏来检查tg_事件
:
触发前触发(tg事件)
如果触发器在操作之前触发,则返回true。
触发器在(tg事件)后触发
如果操作后触发触发器,则返回true。
触发触发触发(tg事件)
如果触发了触发器而不是操作,则返回true。
触发行触发行(tg事件)
如果为行级事件触发触发器,则返回true。
触发器为语句触发(tg事件)
如果为语句级事件触发触发器,则返回true。
触发器由插入触发(tg事件)
如果触发器是由插入
命令
触发由更新触发(tg事件)
如果触发器是由使现代化
命令
触发由删除触发(tg事件)
如果触发器是由删去
命令
触发器由截断触发(tg事件)
如果触发器是由截断
命令
tg_关系
指向描述触发器触发的关系的结构的指针。看看utils/rel。H
有关此结构的详细信息。最有趣的事情是tg_关系->rd_附件
(关系元组的描述符)和tg_关系->rd_关系->关系名称
(关系名称;类型不是炭*
但是名称数据
; 使用SPI_getrelname(tg_关系)
得到一个炭*
如果您需要该名称的副本)。
三元组
指向为其触发触发器的行的指针。这是正在插入、更新或删除的行。如果这个扳机是为了插入
或删去
如果不想用其他行替换该行(在插入
)或者跳过操作。对于外部表上的触发器,此处未指定系统列的值。
tg_新偶
一个指向行的新版本的指针,如果触发器是为使现代化
和无效的
如果是为了插入
或者删去
.如果事件是一个使现代化
您不想用另一行替换这一行,也不想跳过该操作。对于外部表上的触发器,此处未指定系统列的值。
tg_触发器
指向类型结构的指针触发
,定义于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
是扳机的名字,特格纳格斯
是中的参数数tgargs
和tgargs
是指向创建触发器
陈述其他成员仅供内部使用。
三角槽
包含三元组
,或无效的
指针,如果没有这样的元组。
tg_新闻特辑
包含tg_新偶
,或无效的
指针,如果没有这样的元组。
老桌子
指向类型结构的指针树酯
包含零行或多行,格式为tg_关系
,或无效的
指针,如果没有旧桌子
过渡关系。
新表
指向类型结构的指针树酯
包含零行或多行,格式为tg_关系
,或无效的
指针,如果没有新桌子
过渡关系。
tg_更新的cols
对于使现代化
触发器,一个位图集,指示由触发命令更新的列。通用触发器函数可以使用它来优化操作,不必处理未更改的列。
例如,要确定属性号为的列阿特纳姆
(基于1)是此位图集的成员,请调用bms_是_成员(attnum-FirstLowInvalidHeapAttributeNumber,trigdata->tg_updatedcols))
.
对于触发器,而不是使现代化
触发器,这将是无效的
.
要允许通过SPI发出的查询引用转换表,请参阅SPI_登记_触发_数据.
触发器函数必须返回一堆
指针还是指针无效的
指针(不SQL空值,即不设置*isNull
*是的)。小心返回三元组
或tg_新偶
,如果不想修改正在操作的行,请视情况而定。