postgresql-实现自增列的启用和禁用,启用后从最大值开始递增

一、介绍

1、功能介绍:

POSTGRES实现自增列的启用和禁用,启用后自增列从最大值开始递增。

2、函数介绍:

br_on_off_default_value_seq (schema_name in varchar,table_name in varchar,column_name in varchar,on_off_flag in int)
(1)schema_name 模式名
(2)table_name 表名
(3)column_name 列名
(4)on_off_flag 0为禁用,1为启用

二、测试验证

1、创建测试环境:

drop schema br CASCADE;

drop table test_tab;

drop sequence test_seq;

create table test_tab(a int,b varchar);

create sequence test_seq start with 2 increment by 1 minvalue 2  maxvalue 9223372036854775807  no cycle cache 2;

alter table test_tab alter column a set default nextval('test_seq');

insert into test_tab(b) values('sun');

insert into test_tab(b) values('czg');

select * from test_tab;

在这里插入图片描述

2、禁用自增列:

select br_on_off_default_value_seq('public','test_tab','a',0);

3、插入测试数据:

insert into test_tab values(10,'lxg');

insert into test_tab values(12,'haha');

select * from test_tab;

在这里插入图片描述

4、启用自增列:

select br_on_off_default_value_seq('public','test_tab','a',1);

5、测试函数效果

insert into test_tab(b) values('br');

insert into test_tab(b) values('test');

select * from test_tab;

在这里插入图片描述

三、br_on_off_default_value_seq 函数定义

CREATE OR REPLACE FUNCTION br_on_off_default_value_seq (schema_name in varchar,table_name in varchar,column_name in varchar,on_off_flag in int)
RETURNS TEXT
AS $$
temp_schema = 'br'
temp_table = 'br_source_data_tab'

txdb_select_sql = 'select max({column_name}) from {schema_name}.{table_name}'\
.format(schema_name=schema_name,column_name=column_name,table_name=table_name)

txdb_create_source_data_tab = 'create table {schema_name}.{table_name}(schema_name varchar(100),table_name varchar(100),column_name varchar(100),column_max_value varchar(100),default_seq varchar(100),seqstart bigint,seqincrement bigint,seqmax bigint,seqmin bigint,seqcache bigint,seqcycle varchar(10),\
primary key(schema_name,table_name,column_name,column_max_value,default_seq))'\
.format(schema_name=temp_schema,table_name=temp_table)

txdb_create_source_schema = 'create schema {schema_name}'\
.format(schema_name=temp_schema)

txdb_judge_tab_exists = 'select count(*) from pg_tables where tablename =\'{table_name}\' and schemaname=\'{schema_name}\''\
.format(schema_name=temp_schema,table_name=temp_table)

txdb_judge_schema_exists = 'select count(*) from pg_catalog.pg_namespace where nspname=\'{schema_name}\''\
.format(schema_name=temp_schema)

#判断temp_schema模式是否存在-1
sql_pre_judge_schema_exists = plpy.prepare(txdb_judge_schema_exists)
txdb_select_result_judge_schema_exists = plpy.execute(sql_pre_judge_schema_exists)
if txdb_select_result_judge_schema_exists[0]['count'] == 0: 
	sql_pre_txdb_create_source_schema = plpy.prepare(txdb_create_source_schema)
	plpy.execute(sql_pre_txdb_create_source_schema)
	
#判断temp_schema.temp_table表是否存在-2
sql_pre_judge_tab_exists = plpy.prepare(txdb_judge_tab_exists)
txdb_select_result_judge_tab_exists = plpy.execute(sql_pre_judge_tab_exists)
if txdb_select_result_judge_tab_exists[0]['count'] == 0: 
	sql_pre_txdb_create_source_data_tab = plpy.prepare(txdb_create_source_data_tab)
	plpy.execute(sql_pre_txdb_create_source_data_tab)

if on_off_flag == 1:
	#查询传入参数表上包含的默认值序列
	txdb_select_seq_sql = 'SELECT column_default FROM information_schema.columns WHERE (table_schema, table_name) = (\'{schema_name}\', \'{table_name}\') and column_name =\'{column_name}\''\
	.format(schema_name=schema_name,table_name=table_name,column_name=column_name)
	sql_pre_select_seq_sql = plpy.prepare(txdb_select_seq_sql)
	txdb_select_result_select_seq_sql = plpy.execute(sql_pre_select_seq_sql)
	if txdb_select_result_select_seq_sql[0]['column_default'] is not None:
		return '%s模式的%s表上的默认值序列%s为启用状态,不能再启用'%(schema_name,table_name,txdb_select_result_select_seq_sql[0]['column_default'].split("'")[1])
		#序列名为:txdb_select_result_select_seq_sql[0]['column_default'].split("'")[1]	
											   		
	#把表中的最大值更新到临时表中
	sql_pre = plpy.prepare(txdb_select_sql)
	txdb_select_result = plpy.execute(sql_pre)
	txdb_update_source_data_tab = 'update {schema_name}.{table_name} set column_max_value=$1 where schema_name=\'{schema_name_1}\' and table_name=\'{table_name_1}\' and column_name=\'{column_name}\' '\
	.format(schema_name=temp_schema,\
			table_name=temp_table,\
			schema_name_1=schema_name,\
			table_name_1=table_name,\
			column_name=column_name)
	try:
		sql_update_source_data_tab = plpy.prepare(txdb_update_source_data_tab,["text"])
		plpy.execute(sql_update_source_data_tab,[txdb_select_result[0]['max']])
	except BaseException as e:
		return '启用默认值序列阶段,更新临时表数据报错:%s'%(e)												   

	#从临时表中查出序列相关参数
	txdb_select_source_tab = 'select * from {schema_name}.{table_name} where schema_name=\'{schema_name_1}\' and table_name=\'{table_name_1}\' and column_name=\'{column_name}\''\
	.format(schema_name=temp_schema,\
			table_name=temp_table,\
			schema_name_1=schema_name,\
			table_name_1=table_name,\
			column_name=column_name)
	sql_pre_select_source_tab = plpy.prepare(txdb_select_source_tab)
	txdb_select_result_select_source_tab = plpy.execute(sql_pre_select_source_tab)
											   
	#生成序列
	if len(txdb_select_result_select_source_tab) == 0:
		return '请先传入参数0进行默认值序列禁用,再传入参数1进行默认值序列启用'
	elif txdb_select_result_select_source_tab[0]['seqcycle'] == 'True':
		txdb_sequence_cycle_value = 'cycle'																   
	elif txdb_select_result_select_source_tab[0]['seqcycle'] == 'False':
		txdb_sequence_cycle_value = 'no cycle'
	else:
		return '生成序列逻辑判断阶段出现未预见的情况'
	txdb_create_sequence = 'create sequence {schema_name}.{seq_name} start with {start_value} increment by {increment_value} minvalue {min_value}  maxvalue {max_value}  {cycle_value} cache {cache_value}'\
	.format(schema_name=txdb_select_result_select_source_tab[0]['schema_name'],\
			seq_name=txdb_select_result_select_source_tab[0]['default_seq'],\
			start_value=int(txdb_select_result_select_source_tab[0]['column_max_value'])+1,\
			increment_value=txdb_select_result_select_source_tab[0]['seqincrement'],\
			min_value=txdb_select_result_select_source_tab[0]['seqmin'],\
			max_value=txdb_select_result_select_source_tab[0]['seqmax'],\
			cycle_value=txdb_sequence_cycle_value,\
			cache_value=txdb_select_result_select_source_tab[0]['seqcache'])
	sql_pre_create_sequence = plpy.prepare(txdb_create_sequence)
	plpy.execute(sql_pre_create_sequence)	
											   
	#添加序列默认值
	txdb_add_default_value = 'alter table {table_schema}.{table_name} alter column {column_name} set default nextval(\'{seq_schema}.{seq_name}\')'\
	.format(table_schema=txdb_select_result_select_source_tab[0]['schema_name'],\
		   table_name=txdb_select_result_select_source_tab[0]['table_name'],\
		   column_name=txdb_select_result_select_source_tab[0]['column_name'],\
		   seq_schema=txdb_select_result_select_source_tab[0]['schema_name'],\
		   seq_name=txdb_select_result_select_source_tab[0]['default_seq'])
	#return txdb_add_default_value
	sql_pre_add_default_value = plpy.prepare(txdb_add_default_value)
	plpy.execute(sql_pre_add_default_value)	
	
elif on_off_flag == 0:
	#查询传入参数表上包含的默认值序列
	txdb_select_seq_sql = 'SELECT column_default FROM information_schema.columns WHERE (table_schema, table_name) = (\'{schema_name}\', \'{table_name}\') and column_name =\'{column_name}\''\
	.format(schema_name=schema_name,table_name=table_name,column_name=column_name)
	sql_pre_select_seq_sql = plpy.prepare(txdb_select_seq_sql)
	txdb_select_result_select_seq_sql = plpy.execute(sql_pre_select_seq_sql)
	if txdb_select_result_select_seq_sql[0]['column_default'] == None:
		return '%s模式的%s表上没有默认值序列,无法禁用'%(schema_name,table_name)
	#序列名为:txdb_select_result_select_seq_sql[0]['column_default'].split("'")[1]

	#查询序列定义
	txdb_select_seq_define_1 = 'select oid from pg_class where relname=\'{seq_name}\''.format(seq_name=txdb_select_result_select_seq_sql[0]['column_default'].split("'")[1])
	sql_pre_select_seq_define_1 = plpy.prepare(txdb_select_seq_define_1)
	txdb_select_result_select_seq_define_1 = plpy.execute(sql_pre_select_seq_define_1)	
	#序列名oid为:txdb_select_result_select_seq_define_1[0]['oid']
	
	txdb_select_seq_define_2 = 'select seqstart,seqincrement,seqmax,seqmin,seqcache,seqcycle from pg_sequence where seqrelid={oid_value}'.format(oid_value=txdb_select_result_select_seq_define_1[0]['oid'])
	sql_pre_select_seq_define_2 = plpy.prepare(txdb_select_seq_define_2)
	txdb_select_result_select_seq_define_2 = plpy.execute(sql_pre_select_seq_define_2)	
	#序列的定义:txdb_select_result_select_seq_define_2[0]
	
	#判断临时表中有没有传入参数表的数据,如果有进行更新,没有就插入-3
	txdb_judge_source_data_repeat = 'select count(*) from {schema_name}.{table_name} where table_name=\'{table_name_1}\' and column_name=\'{column_name}\''\
	.format(schema_name=temp_schema,table_name=temp_table,table_name_1=table_name,column_name=column_name)
	sql_pre_judge_source_data_repeat = plpy.prepare(txdb_judge_source_data_repeat)
	txdb_select_result_judge_source_data_repeat = plpy.execute(sql_pre_judge_source_data_repeat)
	sql_pre = plpy.prepare(txdb_select_sql)
	txdb_select_result = plpy.execute(sql_pre)
	if txdb_select_result_judge_source_data_repeat[0]['count'] == 0:
		#表中最大值插入到临时表中
		txdb_insert_source_data_tab = 'insert into  {schema_name}.{table_name} values ($1,$2,$3,$4,$5,$6,$7,$8,$9,$10,$11)'\
		.format(schema_name=temp_schema,table_name=temp_table)
		try:
			sql_pre_insert_source_data_tab = plpy.prepare(txdb_insert_source_data_tab,["text","text","text","text","text","bigint","bigint","bigint","bigint","bigint","varchar"])
			plpy.execute(sql_pre_insert_source_data_tab,\
						 [schema_name,\
						 table_name,\
						 column_name,\
						  txdb_select_result[0]['max'],\
						  txdb_select_result_select_seq_sql[0]['column_default'].split("'")[1],\
						  txdb_select_result_select_seq_define_2[0]['seqstart'],\
						  txdb_select_result_select_seq_define_2[0]['seqincrement'],\
						  txdb_select_result_select_seq_define_2[0]['seqmax'],\
						  txdb_select_result_select_seq_define_2[0]['seqmin'],\
						  txdb_select_result_select_seq_define_2[0]['seqcache'],\
						  txdb_select_result_select_seq_define_2[0]['seqcycle']])
		except BaseException as e:
			return '数据无重复逻辑阶段报错:%s'%(e)
	elif txdb_select_result_judge_source_data_repeat[0]['count'] == 1:
		txdb_update_source_data_tab = 'update {schema_name}.{table_name} set column_max_value=$1 where schema_name=\'{schema_name_1}\' and table_name=\'{table_name_1}\' and column_name=\'{column_name}\' '\
		.format(schema_name=temp_schema,\
				table_name=temp_table,\
				schema_name_1=schema_name,\
				table_name_1=table_name,\
				column_name=column_name)
		try:
			sql_update_source_data_tab = plpy.prepare(txdb_update_source_data_tab,["text"])
			plpy.execute(sql_update_source_data_tab,[txdb_select_result[0]['max']])
		except BaseException as e:
			return '数据重复逻辑阶段报错:%s'%(e)	
																					   
	#删除默认值
	txdb_drop_default_seq = 'alter table {schema_name}.{table_name} alter column {column_name} drop default'\
	.format(schema_name=schema_name,table_name=table_name,column_name=column_name)		
	sql_drop_default_seq = plpy.prepare(txdb_drop_default_seq)
	plpy.execute(sql_drop_default_seq)
	
	#删除序列
	txdb_drop_seq = 'drop sequence {seq_name}'\
	.format(seq_name=txdb_select_result_select_seq_sql[0]['column_default'].split("'")[1])		
	sql_drop_seq = plpy.prepare(txdb_drop_seq)
	plpy.execute(sql_drop_seq)
	
else:
	return 'on_off_flag参数,开启为:1,关闭为:0,请不要输入其他值'
return 1

end
$$ LANGUAGE plpython3u;

如果有什么需要改进的地方,欢迎大家一起讨论。

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值