↑↓ 选择↵ 打开⌫ 切换范围完整搜索

PG.CENTER 连接 PostgreSQL 文档、百科与生态知识。由 Pigsty 维护。

支持中的版本: 当前版本 (18) / 17 / 16 / 15 / 14
开发中的版本: 19 / 20devel
已结束支持的版本: 13 / 12 / 11 / 10 / 9.6 / 9.5 / 9.4 / 9.3 / 9.2 / 9.1 / 9.0 / 8.4 / 8.3

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

spi 模块提供了若干使用服务器编程接口(SPI)和触发器的实用示例。虽然这些函数本身也有一定的独立用途,但把它们作为可按自身需求修改的示例来看更有价值。这些函数足够通用,可以用于任何表,但在创建触发器时必须指定表名和字段名(如下所述)。

下文描述的每组函数都作为一个可单独安装的扩展提供。

F.39.1. refint — 用于实现引用完整性的函数 #

check_primary_key() 和 check_foreign_key() 用于检查外键约束。(当然,这项功能早已被内置外键机制取代,不过该模块作为示例仍然很有用。该模块将在 PostgreSQL 20 中移除。)

注意

refint 要求使用模式的安全使用方式,并要求数据类型的等值操作符名为 =。

check_primary_key() 检查引用表。使用时,在引用其他表的表上创建一个使用该函数的 BEFORE INSERT OR UPDATE 触发器。触发器参数依次为:引用表中构成外键的列名、被引用表名,以及被引用表中构成主键/唯一键的列名。若要处理多个外键,请为每个引用分别创建一个触发器。

注意

传给 check_primary_key() 的被引用表名和列名参数会原样复制到内部生成的 SQL 语句中,因此用户必须根据需要在 CREATE TRIGGER 命令中用双引号将它们括起。有关 SQL 标识符引号规则的更多信息,请参见第 4.1.1 节。相反,引用表的列名参数不应使用双引号。以下模拟示例展示了 check_primary_key() 的正确用法:

CREATE TRIGGER mytrigger
BEFORE INSERT OR UPDATE ON referencing_table
FOR EACH ROW EXECUTE PROCEDURE
check_primary_key (
    'column A', 'column B',         -- referencing table columns
    'myschema."referenced table"',  -- referenced table
    '"column A"', '"column B"'      -- referenced table columns
);

check_foreign_key() 检查被引用表。使用时,在被其他表引用的表上创建一个使用该函数的 BEFORE DELETE OR UPDATE 触发器。触发器参数依次为:该函数需要检查的引用表数量、发现引用键时采取的动作(cascade 表示删除引用行,restrict 表示若存在引用键则中止事务,setnull 表示将引用键字段设为空)、被引用表中构成主键/唯一键的列名,然后是引用表名和列名(按第一个参数指定的引用表数量重复提供)。请注意,主键/唯一键列应标记为 NOT NULL,并具有唯一索引。

注意

传给 check_foreign_key() 的引用表名和列名参数会原样复制到内部生成的 SQL 语句中,因此用户必须根据需要在 CREATE TRIGGER 命令中用双引号将它们括起。有关 SQL 标识符引号规则的更多信息,请参见第 4.1.1 节。相反,被引用表的列名参数不应使用双引号。以下模拟示例展示了 check_foreign_key() 的正确用法:

CREATE TRIGGER mytrigger
BEFORE DELETE OR UPDATE ON referenced_table
FOR EACH ROW EXECUTE PROCEDURE
check_foreign_key (
    1,                              -- number of referencing tables
    'cascade',                      -- action
    'column A', 'column B',         -- referenced table columns
    'myschema."referencing table"', -- referencing table
    '"column A"', '"column B"'      -- referencing table columns
);

refint.example 中有示例。

F.39.2. autoinc — 用于字段自动递增的函数 #

autoinc() 是一个将序列的下一个值存入整数字段的触发器。它与内置的“serial 列”功能有一些重叠,但并不相同:autoinc() 会覆盖插入时试图为该字段指定其他值的操作,而且还可以选择在更新时也递增该字段。

使用时,创建一个使用该函数的 BEFORE INSERT(或者可选的 BEFORE INSERT OR UPDATE)触发器。指定两个触发器参数:要修改的整型列名,以及提供这些值的序列对象名。(实际上,如果你希望更新多个自动递增列,也可以指定任意多组这样的名称对。)

autoinc.example 中有一个示例。

F.39.3. insert_username — 用于跟踪谁修改了表的函数 #

insert_username() 是一个将当前用户名存入文本字段的触发器。它有助于跟踪表中某一特定行最后一次是由谁修改的。

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

insert_username.example 中有一个示例。

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

moddatetime() 是一个将当前时间存入 timestamp 字段的触发器。它有助于跟踪表中某一特定行最后一次被修改的时间。

使用时,创建一个使用该函数的 BEFORE UPDATE 触发器。指定一个触发器参数:要修改的列名。该列必须是 timestamp 或 timestamp with time zone 类型。

moddatetime.example 中有一个示例。

报告文档问题

阅读 上游文档. 通过 PostgreSQL 文档反馈表单.