问题描述
--现有数据
create table tbl_Master
(
col_Date date not null,id int not null,value int not null
);
insert into tbl_Master values('2021-01-14',10,21);
insert into tbl_Master values('2020-09-30',11,22);
insert into tbl_Master values('2021-11-28',12,23);
--更改表名
alter table tbl_Master rename to tbl_Master_old;
--按范围分区再次创建主表
create table tbl_Master(
col_Date date not null,value int not null
) partition by range (col_Date);
--功能:
create or replace function fn_create_partition(col_Date date) returns void
as
$body$
declare v_startDate date := date_trunc('month',col_Date)::date;
declare v_EndDate date := (v_startDate + interval '1 month')::date;
declare tableName text := 'tbl_Master_Part_' || to_char(col_Date,'YYYYmm');
begin
if to_regclass(tableName) is null then
execute format('create table %I partition of tbl_Master for values from (%L) to (%L)',tableName,v_startDate,v_EndDate);
end if;
end;
$body$
language plpgsql;
--为现有数据创建分区表
do
$$
declare rec record;
begin
for rec in select distinct date_trunc('month',col_Date)::date yearmonth from tbl_Master_old
loop
perform fn_create_partition(rec.yearmonth);
end loop;
end
$$;
--插入备份数据
insert into tbl_Master (col_Date,id,value) select * from tbl_Master_old;
--当我插入记录时
insert into tbl_Master values('2021-02-22',22);
出现错误:
ERROR: no partition of relation "tbl_master" found for row DETAIL: Partition key of the failing row contains (col_date) = (2021-02-22).
所以我为此创建了规则:
--规则
create or replace rule rule_fn_create_partition as on insert
to tbl_Master
do instead
(
select fn_create_partition(NEW.col_Date);
insert into tbl_Master values(New.*)
);
--当我插入记录时
insert into tbl_Master values('2021-02-22',22);
出现错误:
ERROR: infinite recursion detected in rules for relation "tbl_master"
解决方法
规则包含一个 INSERT
,所以这是一个无限递归。
您不能让 PostgreSQL 在您插入数据时自动创建分区。它只是不起作用。触发器也不起作用。问题是这需要在插入过程中修改基础表。