0
点赞
收藏
分享

微信扫一扫

PostgreSQL重置所有Sequence启始值

王远洋 2022-09-24 阅读 68

目录

  • ​​适用范围​​
  • ​​方案概述​​
  • ​​实施步骤​​
  • ​​1.sequence为表自增主键​​
  • ​​2.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语句。

PostgreSQL重置所有Sequence启始值_主键



举报

相关推荐

0 条评论