PG DDL事件触发器无法正常工作

问题描述

我试图通过PostgreSQL中的事件触发器来拦截CREATE TABLE,以禁止创建不符合某些命名规则的表。我的代码如下:

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 in ('CREATE TABLE')
   LOOP
        if  NOT  obj.object_identity LIKE 't?_%' ESCAPE '?'
        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();

当我尝试:

CREATE TABLE t_toto3 (i INT)

我系统地出现以下错误:

错误:表名必须以t_
开头 内容:功能PL / pgSQL e_ddl_create_table_func(),ligne 11àRAISE

我想念什么?

解决方法

the docsprintString是模式限定的。在您的示例中它将以object_identity的形式出现(除非您使用其他默认架构进行了非常非标准的设置);您可以通过将表格组件传递给parse_ident()并提取第二项来获得表格组件。 (请注意最后parse_ident()周围的多余parens,以便正确解析数组查找。)

'public.t_toto3'
,

是的,它可以与parse_ident一起使用。解决方法是:

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 in ('CREATE TABLE')
   LOOP
        if  NOT  (parse_ident(obj.object_identity))[2] LIKE 't?_%' ESCAPE '?'
        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:Request method ‘DELETE‘ not supported 错误还原:...
错误1:启动docker镜像时报错:Error response from daemon:...
错误1:private field ‘xxx‘ is never assigned 按Alt...
报错如下,通过源不能下载,最后警告pip需升级版本 Requirem...