Postgresql - SQL 查询列出数据库中的所有序列

标签 postgresql sequence plpgsql dynamic-sql catalog

我想选择数据库中的所有序列,获取序列的模式、依赖表、表的模式、依赖列。

我尝试了以下查询:

  SELECT 
    ns.nspname AS sequence_schema_name, 
    s.relname AS sequence_name, 
    t_ns.nspname AS table_schema_name, 
    t.relname AS table_name, 
    a.attname AS column_name,
    s.oid,
    s.relnamespace,
    d.*,
    a.*
  FROM pg_class s
  JOIN pg_namespace ns 
  ON ns.oid = s.relnamespace
  left JOIN pg_depend d --
  ON d.objid = s.oid --TO FIX???
    AND d.classid = 'pg_class'::regclass --TO FIX???
    AND d.refclassid = 'pg_class'::regclass --TO FIX???
  left JOIN pg_class t 
  ON t.oid = d.refobjid --TO FIX???
  left JOIN pg_attribute a 
  ON a.attrelid = d.refobjid 
     AND a.attnum = d.refobjsubid
  left JOIN pg_namespace t_ns 
  ON t.relnamespace = t_ns.oid
  WHERE s.relkind = 'S' 
;

不幸的是,这个查询不能 100% 正常工作。查询过滤一些序列。

我需要它进行进一步处理(在不同ENV上恢复数据后,我需要找到最大列值并将序列设置为MAX+1)。

有人可以帮助我吗?

最佳答案

以下查询应该有效:

create table foo(id serial, v integer);
create table boo(id_boo serial, v integer);
create sequence omega;
create table bubu(id integer default nextval('omega'), v integer);

select sn.nspname as seq_schema,
       s.relname as seqname,
       st.nspname as tableschema,
       t.relname as tablename,
       at.attname as columname
  from pg_class s
  join pg_namespace sn on sn.oid = s.relnamespace
  join pg_depend d on d.refobjid = s.oid 
  join pg_attrdef a on d.objid = a.oid
  join pg_attribute at on at.attrelid = a.adrelid and at.attnum = a.adnum
  join pg_class t on t.oid = a.adrelid
  join pg_namespace st on st.oid = t.relnamespace
 where s.relkind = 'S'
   and d.classid = 'pg_attrdef'::regclass
   and d.refclassid = 'pg_class'::regclass;
┌────────────┬────────────────┬─────────────┬───────────┬───────────┐
│ seq_schema │    seqname     │ tableschema │ tablename │ columname │
╞════════════╪════════════════╪═════════════╪═══════════╪═══════════╡
│ public     │ foo_id_seq     │ public      │ foo       │ id        │
│ public     │ boo_id_boo_seq │ public      │ boo       │ id_boo    │
│ public     │ omega          │ public      │ bubu      │ id        │
└────────────┴────────────────┴─────────────┴───────────┴───────────┘
(3 rows)

要调用与序列相关的函数,您可以使用s.oid列。对于这种情况,它是序列唯一的 oid 标识符。您需要将其转换为regclass

您请求的脚本可能如下所示:

do $$
declare
  r record;
  max_val bigint;
begin
  for r in
    select s.oid as seqoid,
           at.attname as colname,
           a.adrelid as reloid
      from pg_class s
      join pg_namespace sn on sn.oid = s.relnamespace
      join pg_depend d on d.refobjid = s.oid 
      join pg_attrdef a on d.objid = a.oid
      join pg_attribute at on at.attrelid = a.adrelid and at.attnum = a.adnum
     where s.relkind = 'S'
       and d.classid = 'pg_attrdef'::regclass 
       and d.refclassid = 'pg_class'::regclass
  loop
    -- probably lock here can be safer, in safe (single user) maintainance mode
    -- it is not necessary
    execute format('lock table %s in exclusive mode', r.reloid::regclass);

    -- expect usual one sequnce per table
    execute format('select COALESCE(max(%I),0) from %s', r.colname, r.reloid::regclass)
       into max_val;

    -- set sequence
    perform setval(r.seqoid, max_val + 1);
  end loop;
end;
$$

注意:在format函数中使用%s作为表名或序列名是安全的,因为从Oid类型到的转换>regclass类型生成安全字符串(每次需要时使用schema,每次需要时使用转义)。

关于Postgresql - SQL 查询列出数据库中的所有序列,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63022401/

相关文章:

javascript - 如何在javascript中从左到右从字符串序列中选择数字整数

c# - 查找序列中缺失和重叠的数字

ruby-on-rails - INSERT RETURNING 和分区 POSTGRESQL

sql - 从函数返回默认的 INSERT INTO 消息

postgresql - AFTER INSERT PostgreSQL 触发器的意外行为

postgresql - 如何返回表的行类型加上函数的附加列?

PostgreSQL 时间戳 BIRT 参数

sql - 如果 from 和 to date 为空,如何获取最近 7 天的数据?

postgresql - 我如何在 postgresql 中使用 GMT 时间?

java - JPA hibernate : Invalid persistence. xml