在 PG 12 或 PG 13 中声明系统触发器名称
Declaring system trigger names in PG 12 or PG 13
我刚刚注意到FOREIGN KEY
等约束会自动生成系统触发器,并将它们命名为RI_ConstraintTrigger_a or _c + trigger oid
。我查看了文档,但没有看到在 FOREIGN KEY
等中为这些触发器声明名称的方法。我很在意,因为我正在编写一些检查代码来比较两个不同数据库中的对象。系统触发器的本地名称各不相同,因为 oid 自然会有所不同。
有没有办法在创建这些触发器时为其声明名称?如果是这样,这样做有什么坏处吗?我想我读到在恢复或升级后,触发器和相关函数名称可能会重新生成。如果是这样,在这些项目上使用 RENAME TRIGGER
就像逆流而上……我怀疑这是个坏主意。
我想我可以通过查询 pg_trigger
其他属性的组合来找到触发器的本地名称...但我没有看到触发器的独特之处,apart 来自它的唯一名称。我能想到的就是搜索 pg_get_triggerdef(oid),然后比较输出。
对于那些在家学习的人,这里有一个创建几个系统触发器的“hello world”示例。
DROP TABLE if exists calendar_child CASCADE;
CREATE TABLE calendar_child
(
id uuid NOT NULL DEFAULT extensions.gen_random_uuid() PRIMARY KEY,
calendar_id uuid NOT NULL DEFAULT NULL
);
ALTER TABLE calendar_child
ADD CONSTRAINT calendar_year_calendar_fk
FOREIGN KEY (calendar_id) REFERENCES calendar(id)
ON DELETE CASCADE;
select oid,tgrelid::regclass,tgname from pg_trigger where tgrelid::regclass::text = 'calendar_child';
+--------+----------------+-------------------------------+
| oid | tgrelid | tgname |
+--------+----------------+-------------------------------+
| 355281 | calendar_child | RI_ConstraintTrigger_c_355281 |
| 355282 | calendar_child | RI_ConstraintTrigger_c_355282 |
+--------+----------------+-------------------------------+
这是 pg_get_triggerdef
returns.
的简单格式示例
CREATE CONSTRAINT TRIGGER "RI_ConstraintTrigger_a_352380"
AFTER DELETE ON calendar FROM calendar_year
NOT DEFERRABLE INITIALLY
IMMEDIATE FOR EACH ROW EXECUTE FUNCTION "RI_FKey_cascade_del"()
链接的函数名称不是动态命名的,它们似乎是对标准行为的 C 例程的调用,可在 https://doxygen.postgresql.org/ri__triggers_8c_source.html 中找到。
不支持更改这些触发器的名称,一般不支持重命名触发器。
比较这些触发器名称没有意义,因为它们只是外键约束的实现细节。约束可以重命名,可以用pg_get_constraintdef
函数获取约束定义。那才是你应该比较的。
我刚刚注意到FOREIGN KEY
等约束会自动生成系统触发器,并将它们命名为RI_ConstraintTrigger_a or _c + trigger oid
。我查看了文档,但没有看到在 FOREIGN KEY
等中为这些触发器声明名称的方法。我很在意,因为我正在编写一些检查代码来比较两个不同数据库中的对象。系统触发器的本地名称各不相同,因为 oid 自然会有所不同。
有没有办法在创建这些触发器时为其声明名称?如果是这样,这样做有什么坏处吗?我想我读到在恢复或升级后,触发器和相关函数名称可能会重新生成。如果是这样,在这些项目上使用 RENAME TRIGGER
就像逆流而上……我怀疑这是个坏主意。
我想我可以通过查询 pg_trigger
其他属性的组合来找到触发器的本地名称...但我没有看到触发器的独特之处,apart 来自它的唯一名称。我能想到的就是搜索 pg_get_triggerdef(oid),然后比较输出。
对于那些在家学习的人,这里有一个创建几个系统触发器的“hello world”示例。
DROP TABLE if exists calendar_child CASCADE;
CREATE TABLE calendar_child
(
id uuid NOT NULL DEFAULT extensions.gen_random_uuid() PRIMARY KEY,
calendar_id uuid NOT NULL DEFAULT NULL
);
ALTER TABLE calendar_child
ADD CONSTRAINT calendar_year_calendar_fk
FOREIGN KEY (calendar_id) REFERENCES calendar(id)
ON DELETE CASCADE;
select oid,tgrelid::regclass,tgname from pg_trigger where tgrelid::regclass::text = 'calendar_child';
+--------+----------------+-------------------------------+
| oid | tgrelid | tgname |
+--------+----------------+-------------------------------+
| 355281 | calendar_child | RI_ConstraintTrigger_c_355281 |
| 355282 | calendar_child | RI_ConstraintTrigger_c_355282 |
+--------+----------------+-------------------------------+
这是 pg_get_triggerdef
returns.
CREATE CONSTRAINT TRIGGER "RI_ConstraintTrigger_a_352380"
AFTER DELETE ON calendar FROM calendar_year
NOT DEFERRABLE INITIALLY
IMMEDIATE FOR EACH ROW EXECUTE FUNCTION "RI_FKey_cascade_del"()
链接的函数名称不是动态命名的,它们似乎是对标准行为的 C 例程的调用,可在 https://doxygen.postgresql.org/ri__triggers_8c_source.html 中找到。
不支持更改这些触发器的名称,一般不支持重命名触发器。
比较这些触发器名称没有意义,因为它们只是外键约束的实现细节。约束可以重命名,可以用pg_get_constraintdef
函数获取约束定义。那才是你应该比较的。