PostgreSQL 创建分区表,SQL优化之PostgreSQL Table Partitioning
PostgreSQL中使用动态SQL-实现自动按时间创建表分区
declare
createOn varchar(32);
createYY varchar(4);
tableName VARCHAR(48);
isExist int;
r record;
sqlStr text;
sqlDel text;
sqlIn text;
begin
//通过以下语句给createOn变量赋值
select start_time into createOn from tech_trial_t where start_time <>'' order by start_time asc limit 1;
createYY := substr(createOn, 1,4);
select count(*) into isExist from pg_class where relname = 'tech_trial_t_y' || createYY;
if (isExist=0) then
sqlStr='create table if not exists tech_trial_t_y' || createYY || ' (like tech_trial_t_y2017 including indexes);';
execute sqlStr;
end if;
sqlStr := 'select relname from pg_class where relname like ''tech_trial_t_y20%'' and relname not like ''%_idx'';';
//必须排除索引,因为relname 是表格,索引,视图等的名称
//for 语句循环取值赋值
for r in execute sqlStr loop
sqlDel := 'truncate table ' || r.relname;
EXECUTE sqlDel;
//直接写 truncate table r.relname; 不能执行,貌似不能知道r.relname是什么东东。
所以写成字符串语句执行字符串语句。
sqlIn := 'insert into ' || r.relname || ' select * from tech_trial_t_view_year tv where tv.start_time >= substr( ''' ||r.relname || ''',15,4) ||''-01-01 00:00:00'' and tv.start_time <= substr('''|| r.relname ||''',15,4) ||''-12-31 23:59:59'';';
EXECUTE sqlIn;
end loop;
return NULL;
end
DECLARE start_text TEXT;
DECLARE insert_statement TEXT;
BEGIN
start_text := substr(NEW.start_time, 1 ,4);
insert_statement := 'INSERT INTO tech_trial_t_'
|| start_text
||' VALUES ($1.*)';
EXECUTE insert_statement USING NEW;
RETURN NULL;
EXCEPTION
WHEN UNDEFINED_TABLE
THEN
EXECUTE
'CREATE TABLE IF NOT EXISTS tech_trial_t_'
|| start_text
|| '(CHECK (start_time >= '''
|| start_text
|| '-01-01 00:00:00'' and start_time < ''' || start_text || '-12-31 23:59:59'')) INHERITS (tech_trial_t_year)';
RAISE NOTICE 'CREATE NON-EXISTANT TABLE tech_trial_t_year_%', start_text;
EXECUTE
'CREATE INDEX tech_trial_t_key_'
|| start_text
|| ' ON tech_trial_t_'
|| start_text
|| '(start_time)';
EXECUTE insert_statement USING NEW;
RETURN NULL;
END;
//必须保证每条插入的start_time(分区关键字)非空。
NEW表示新插入的记录