一、介绍
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;
如果有什么需要改进的地方,欢迎大家一起讨论。