1. 程式人生 > >postgresql 分表規則實時修改

postgresql 分表規則實時修改

postgresql資料庫支援資料庫分表,但是有時會遇到,現場的資料庫已經在跑了,但是新的需求,需要增加一個欄位,
欄位增加,分表會自動增加的,但是規則不會實時更新,規則不更新的話,分表新的欄位的值就不會更新掉。
其實只需要把所有的規則修改下就可以了,但是有時規則比較多,手動修改還是有點麻煩,所以,就寫了一個函式來
做這個功能,這個使用起來還是很快很方便的,這裡使用到的就是遊標、函式
-------------該函式只需要主表名稱和時間欄位,即可針對主表字段有增加、修改、刪除的情況時,一鍵修改規則------------------------------
----------------------------定製專案有時會遇到有分表需要增加欄位的情況,但是現場不會重新安裝,但是----------------------------------------------------------------
create
or replace function cursor_demo (
	tabname character varying,
	timefield character varying
) returns refcursor as $body$ declare
	sub_tab_name varchar (1000) ; column_name_desc varchar (1000) ; declare
		fetch_sub_tab_refcursor cursor for select
			tablename
		from
			pg_tables
		where
			tablename like tabname || '_%' ; declare
				fetch_sub_column_refcursor cursor for select
					column_name
				from
					information_schema. columns
				where
					table_name = tabname ; declare
						sql_desc varchar (1000) ; declare
							value_desc varchar (1000) ; declare
								all_sql_desc varchar (2000) ; declare
									st_time varchar (100) ;
								begin
									open fetch_sub_tab_refcursor ; loop fetch fetch_sub_tab_refcursor into sub_tab_name ;
								if found then

								if (
									length (tabname) = (length(sub_tab_name) - 7)
								) then

								if (
									tabname = (
										substring (
											sub_tab_name
											from
												1 for length (tabname)
										)
									)
								) then
									st_time := substring (
										sub_tab_name
										from
											length (tabname) + 2 for length (sub_tab_name)
									) ; st_time := substring (st_time from 1 for 4) || '-' || substring (st_time from 5 for 6) ; sql_desc := 'create or replace rule insert_' || sub_tab_name || ' as on insert to ' || tabname || ' where new.' || timefield || ' >= ''' || substring (
										to_char(
											to_timestamp(st_time, 'yyyy-mm-dd'),
											'yyyy-mm-dd'
										)
										from
											1 for 10
									) || '''::date and new.' || timefield || ' <''' || substring (
										to_char(
											to_timestamp(st_time, 'yyyy-mm-dd') + interval '1 month',
											'yyyy-mm-dd'
										)
										from
											1 for 10
									) || '''::date do instead insert into ' || sub_tab_name || '(' ; value_desc := 'values (' ; open fetch_sub_column_refcursor ; loop fetch fetch_sub_column_refcursor into column_name_desc ;
								if found then
									sql_desc := sql_desc || column_name_desc || ',' ; value_desc := value_desc || 'new.' || column_name_desc || ',' ;
								else
									exit ;
								end
								if ;
								end loop ; sql_desc := substring (
									sql_desc
									from
										1 for length (sql_desc) - 1
								) || ')' ; value_desc := substring (
									value_desc
									from
										1 for length (value_desc) - 1
								) || ');' ; all_sql_desc := sql_desc || value_desc ;  execute all_sql_desc ; close fetch_sub_column_refcursor ;
							else

							end
							if ;
							else

							end
							if ;
							else 
								exit ;
							end
							if ;
							end loop ; close fetch_sub_tab_refcursor ;  return fetch_sub_tab_refcursor ; exception
							when others then
								raise exception 'error--(%)',
								sqlerrm ;
							end ; $body$ language plpgsql;

--------呼叫方式----有兩個引數,第一個是主表名,第二個是根據哪個欄位進行分表------  
begin
;

select
	cursor_demo (
		'your_table_name',
		'your_field'
	);

commit;