PostgreSQL重置所有Sequence启始值

适用范围

pg12+

方案概述

在从ORACLE迁移到PG的过程中,当导入数据后,在启动应用时,Sequence 往往是从1开始,数表的的数据肯定是是超过1的,这时插入数据库会失败。
这时需要我们手动重设Sequence ,以保证Sequence 能正常插入到中而与表里原来的数据不冲突。

实施步骤

1.sequence为表自增主键

在设计数据库,因为主键字段都是id,且设置了自增,便编写了一个脚本,将所有包含id自增字段的表的sequence重置为目前最大id。以后导入数据后重新执行一遍即可。

DO $$ DECLARE
TABLE_NAME TEXT;
maxid INT;
BEGIN
        FOR TABLE_NAME IN (
        SELECT
            tb.TABLE_NAME 
        FROM
            information_schema.tables AS tb
            INNER JOIN information_schema.COLUMNS AS cols ON tb.TABLE_NAME = cols.TABLE_NAME 
        WHERE
            tb.table_catalog = 'dncsdb' 
            AND tb.table_schema = 'public' 
            AND cols.COLUMN_NAME = 'id' 
        )
        LOOP
        EXECUTE'SELECT MAX(id) +1 FROM ' || TABLE_NAME || ';' INTO maxid;
    IF
        maxid IS NOT NULL THEN
            raise notice '%',
            'set sequence ' || TABLE_NAME || '_id_seq  restart with ' || maxid;
        EXECUTE 'alter sequence ' || TABLE_NAME || '_id_seq  restart with ' || maxid || ';';

    END IF;

END LOOP;

END $$;

2.sequence不是表的自增主键

如有SEQ 没有在建表语句中,而是在使用的才用,那么这时就不好判断, 这个SEQ属于那一个表.如果不知道,那个SEQ属于那个表, 我们以最大表为基准。 将所有SEQ的启始值,从最大表的行数开始

#a.指定用户查询表的行数
SELECT
	relname,relowner,
	reltuples 
FROM
	pg_class 	CLS 
    LEFT JOIN pg_namespace N ON ( N.oid = CLS.relnamespace ) 
   	LEFT JOIN pg_authid au ON  (CLS.relowner=au.oid)
WHERE
	nspname NOT IN ( 'pg_catalog', 'information_schema','postgres' ) 
    and au.rolname='ahser'
	AND relkind = 'r' 
ORDER BY
	reltuples DESC;

#b.根据上表查询的最大行数值 ,浮动1000 在设置, 我们查最大表行数为44000,而且通过 count计算也确实是44000,所以我们直接将所有SEQ的起始值设为44000
   select 'alter sequence  IF EXISTS '||relname ||'  start with 44000   MAXVALUE 99999999;;' 
   from pg_class CLS
   LEFT JOIN pg_authid au ON  (CLS.relowner=au.oid)
   where relkind='S'
  and au.rolname='ahser';

#c.在psql中执行 b所生成的动态SQL语句。

posted @ 2022-09-18 18:15  www.cqdba.cn  阅读(668)  评论(0编辑  收藏  举报