You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

PostgreSQL事件触发器拦截CREATE TABLE失效问题排查

问题原因分析

你的问题出在对pg_event_trigger_ddl_commands()返回字段的理解偏差上:object_identity字段返回的是包含模式(Schema)前缀的完整对象标识,比如在默认的public模式下,创建t_toto3表时,object_identity的值是public.t_toto3,而非单纯的t_toto3。

你的匹配条件NOT obj.object_identity LIKE 't?_%' ESCAPE '?'是在检查字符串是否以t_开头,但实际字符串以public.开头,导致条件永远为真,每次创建表都会触发异常。

解决方案

你需要使用object_name字段获取不带模式前缀的纯表名,再检查这个字段是否符合命名规则。修改后的完整代码如下:

修改后的函数与触发器

CREATE OR REPLACE FUNCTION e_ddl_create_table_func() 
RETURNS event_trigger 
LANGUAGE plpgsql 
AS $$ 
DECLARE 
    obj record; 
BEGIN 
    FOR obj IN SELECT * FROM pg_event_trigger_ddl_commands() WHERE command_tag = 'CREATE TABLE' 
    LOOP 
        -- 用object_name获取纯表名,校验是否以t_开头
        IF NOT obj.object_name LIKE 't_%' THEN 
            RAISE EXCEPTION 'The table name must begin with t_'; 
        END IF; 
    END LOOP; 
END; 
$$;

CREATE EVENT TRIGGER trg_create_table 
ON ddl_command_end 
WHEN TAG IN ('CREATE TABLE') 
EXECUTE PROCEDURE e_ddl_create_table_func();

测试验证

  1. 执行合法创建语句:
CREATE TABLE t_toto3 (i INT);

此时不会触发异常,表将正常创建。

  1. 执行非法创建语句:
CREATE TABLE test_table (i INT);

会触发预期的异常:

ERROR: The table name must begin with t_
CONTEXT: fonction PL/pgSQL e_ddl_create_table_func(), ligne 10 à RAISE

补充说明

如果需要同时限制模式下的命名规则(比如要求任意模式下的表名都以t_开头),可以结合object_identity做更复杂的匹配:

IF NOT obj.object_identity LIKE '%.t_%' THEN
    RAISE EXCEPTION 'The table name must begin with t_ (in any schema)';
END IF;

这个条件会校验任意模式下的表名是否以t_开头。

内容的提问来源于stack exchange,提问作者SQLpro

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.09 13:33:12