微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

postgresql恢复数据, 自增处理

postgresql恢复数据, 自增处理

pg中有一个自增类型, serial
serial类型会创建一个序列, sequence
使用pg_dump备份数据并不会记录sequence的最大值
在恢复数据时, 序列会重建, 起始值为0

解决这个问题, 要么在pg_dump时指定生成insert语句
insert语句会触发sequence, 理所当然的会将序列最大值恢复
认是copy csv格式
insert的速度 会比copy慢些
要么手动指定序列最大值

我的做法

drop function if exists restore_seq ();
create or replace function restore_seq()
  returns void as $$
declare
    statements cursor for
    -- 序列, 跟字段本身是没有关系的, 一个序列可以被多个字段使用, 可以手动使用
    -- 这个SQL查询了当前database中所有认值为自增类型的字段
    -- 通过拼接查询得到的table_name, column_name得到序列的名字
    -- 然后通过select max 重新设置序列的起始值
    -- 此方法限制有二, 1: 序列名不要改动, 使用pg认的即可 2: 一个序列不要被多个字段共用
    select c.table_schema, c.table_name, c.column_name, c.column_default
    from @R_242_4045@ion_schema.columns c
           inner join pg_catalog.pg_statio_all_tables st 
               on c.table_schema = st.schemaname and c.table_name = st.relname
           left join pg_catalog.pg_description pgd 
               on (pgd.objoid = st.relid and pgd.objsubid = c.ordinal_position)
    where c.column_default :: text like '%nextval%'
  /*
      and c.table_catalog = 'demo'
      and c.table_schema = 'test'
      and c.table_name = 't_b'
  */;
  declare seq_full_name      text;
  declare table_full_name    text;
  declare max_value          bigint = 1;
  declare query_max_sql      text;
  declare alter_sequence_sql text;
begin
  for stmt in statements loop
    seq_full_name := stmt.table_name || '_' || stmt.column_name || '_seq';
    table_full_name := stmt.table_schema || '.' || stmt.table_name;
    query_max_sql := ('select max(' || stmt.column_name || ') from ' || table_full_name);
    /*
    raise notice '%', seq_full_name;
    raise notice '%', table_full_name;
    raise notice '%', query_max_sql;
   */
    execute query_max_sql
    into max_value;
   
    alter_sequence_sql := ('alter sequence ' || seq_full_name || ' restart with ' || max_value);
    raise notice '%', alter_sequence_sql;
    
    execute alter_sequence_sql;
  end loop;
end;
$$
language plpgsql;

select restore_seq();

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。

相关推荐