PostgreSQL 想实现通过触发器来实现插入新数据前自动创建新的分区表

插入数据的时候,提示错误,求解决

错误信息:

我的代码:

--主表结构
drop table pt_test;
create table pt_test
(
tm date,
id numeric(5,0),
name character varying(100)
);

--自动创建分表函数
create or replace function pt_test_add()
returns trigger as $$
declare
v_is_exist varchar(10);
v_tbl varchar(20);
v_pt_tbl varchar(50);
v_sql varchar(1000);
v_date varchar(20);
begin
	v_date=to_char(new.tm,'yyyymmdd');
	v_tbl='pt_test';
	v_pt_tbl=v_tbl||'_'||v_date;
	
	select count(*) into v_is_exist from pg_class where relname=v_pt_tbl;
	
	if v_is_exist=0 then 
		v_sql:='create table '||v_pt_tbl||' () inherits ('||v_tbl||');';
		execute v_sql;
		raise notice '$',v_sql;
        else 
		raise notice '表已存在,无需创建。';
	end if;
	return null;
end;
$$ language 'plpgsql' volatile cost 100;

--触发器
create triggrt pt_test_trg
	before insert 
	on pt_test
	for each row
execute procedure pt_test_add();

--插入语句测试
insert into pt_test values(date'2021-1-1',1,'a');

根据你提供的代码和错误信息,我发现你在创建分区表时没有指定任何列,从而导致出现了错误信息。你可以修改函数的代码,指定分区表的列,具体的修改如下:

--自动创建分表函数
create or replace function pt_test_add()
returns trigger as $$
declare
v_is_exist varchar(10);
v_tbl varchar(20);
v_pt_tbl varchar(50);
v_sql varchar(1000);
v_date varchar(20);
begin
  v_date=to_char(new.tm,'yyyymmdd');
  v_tbl='pt_test';
  v_pt_tbl=v_tbl||'_'||v_date;
  
  select count(*) into v_is_exist from pg_class where relname=v_pt_tbl;
  
  if v_is_exist=0 then 
    v_sql:='create table '||v_pt_tbl||' (like '||v_tbl||' including all) inherits ('||v_tbl||');';
    execute v_sql;
    raise notice '$',v_sql;
  else 
    raise notice '表已存在,无需创建。';
  end if;
  return null;
end;
$$ language 'plpgsql' volatile cost 100;

修改分区表的创建语句,添加 like 子句来指定分区表的列,从而解决错误。同时,遇到错误时,你也可以通过读取错误信息来了解更多有关错误的信息。

希望这些信息能够帮助你解决你的问题,如果你还有其他问题,可以继续向我咨询。