2025年9月25日: PostgreSQL 18 发布!
支持的版本: 当前 (18) / 17 / 16 / 15 / 14 / 13
开发版本: devel
不支持的版本: 12 / 11 / 10 / 9.6 / 9.5 / 9.4 / 9.3 / 9.2 / 9.1 / 9.0 / 8.4 / 8.3

F.41. spi — 服务器编程接口特性/示例 #

spi 模块提供了几个可用的示例,演示了如何使用 服务器编程接口 (SPI) 和触发器。虽然这些函数本身就具有一定的价值,但它们更适合作为您修改以供自己使用的示例。这些函数足够通用,可以与任何表一起使用,但您必须在创建触发器时指定表名和字段名(如下所述)。

下面描述的每组函数都作为独立安装的扩展提供。

F.41.1. refint — 实现参照完整性的函数 #

check_primary_key()check_foreign_key() 用于检查外键约束。(当然,此功能早已被内置的外键机制取代,但该模块仍可作为示例使用。)

check_primary_key() 检查引用表。要使用它,请在引用另一个表的表上使用此函数创建一个 AFTER INSERT OR UPDATE 触发器。在触发器参数中指定:构成外键的引用表的列名、被引用表名以及被引用表中构成主键/唯一键的列名。要处理多个外键,请为每个引用创建一个触发器。

check_foreign_key() 检查被引用表。要使用它,请在被其他表引用的表上使用此函数创建一个 AFTER DELETE OR UPDATE 触发器。在触发器参数中指定:函数需要执行检查的引用表的数量,如果找到引用键时的操作(cascade — 删除引用行,restrict — 如果存在引用键,则中止事务,setnull — 将引用键字段设置为 null),触发表的列名,这些列构成主键/唯一键,然后是引用表名和列名(根据第一个参数指定的引用表的数量重复)。请注意,主键/唯一键列应标记为 NOT NULL 并应具有唯一索引。

请注意,如果这些触发器是从另一个 BEFORE 触发器执行的,它们可能会意外失败。例如,如果用户插入 row1,然后 BEFORE 触发器插入 row2 并调用带有 check_foreign_key() 的触发器,那么 check_foreign_key() 函数将看不到 row1 并会失败。

refint.example 中有示例。

F.41.2. autoinc — 自增字段的函数 #

autoinc() 是一个触发器,它将序列的下一个值存储到整数字段中。这与内置的“序列化列”功能有些重叠,但并不相同。该触发器仅在字段值为零或 null(在插入或更新行的 SQL 语句的操作之后)时替换该字段的值。此外,如果序列的下一个值为零,nextval() 将被调用第二次以获得非零值。

要使用它,请使用此函数创建一个 BEFORE INSERT(或可选的 BEFORE INSERT OR UPDATE)触发器。指定两个触发器参数:要修改的整数列的名称,以及将提供值的序列对象的名称。(实际上,您可以指定任意数量的此类名称对,如果您想更新多个自增列。)

autoinc.example 中有一个示例。

F.41.3. insert_username — 跟踪谁更改了表的函数 #

insert_username() 是一个触发器,它将当前用户的名称存储到文本字段中。这对于跟踪谁最后修改了表中的特定行很有用。

要使用它,请使用此函数创建一个 BEFORE INSERT 和/或 UPDATE 触发器。指定一个触发器参数:要修改的文本列的名称。

insert_username.example 中有一个示例。

F.41.4. moddatetime — 跟踪最后修改时间的函数 #

moddatetime() 是一个触发器,它将当前时间存储到 timestamp 字段中。这对于跟踪表中特定行的最后修改时间很有用。

要使用它,请使用此函数创建一个 BEFORE UPDATE 触发器。指定一个触发器参数:要修改的列的名称。该列的类型必须为 timestamptimestamp with time zone

moddatetime.example 中有一个示例。

提交更正

如果您在文档中发现任何不正确、与您的实际使用体验不符或需要进一步澄清的内容,请使用 此表单 报告文档问题。