Список всех последовательностей в Postgres db 8.1 с SQL

Я конвертирую БД из postgres в mysql.

поскольку я не могу найти инструмент, который делает сам трюк, я собираюсь преобразовать все последовательности postgres в идентификаторы autoincrement в mysql со значением autoincrement.

Итак, как я могу перечислить все последовательности в Postgres DB (8.1 версия) с информацией о таблице, в которой она используется, следующее значение и т. д. с SQL-запросом?

имейте в виду, что я не могу использовать information_schema.sequences посмотреть в релиз 8.4.

14 ответов


следующий запрос дает имена всем последовательностям.

SELECT c.relname FROM pg_class c WHERE c.relkind = 'S';

обычно последовательность называется ${table}_id_seq. Простое сопоставление шаблонов regex даст вам имя таблицы.

чтобы получить последнее значение последовательности использовать следующий запрос:

SELECT last_value FROM test_id_seq;

Run:psql -E, а потом \ds


обратите внимание, что начиная с PostgreSQL 8.4 вы можете получить все информация о последовательностях, используемых в базе данных через:

SELECT * FROM information_schema.sequences;

поскольку я использую более высокую версию PostgreSQL (9.1) и искал один и тот же ответ повсюду, я добавил этот ответ для потомства и для будущих искателей.


после небольшой боли, я получил его.

лучший способ достичь этого-перечислить все таблицы

select * from pg_tables where schemaname = '<schema_name>'

и затем для каждой таблицы перечислите все столбцы с атрибутами

select * from information_schema.columns where table_name = '<table_name>'

затем для каждого столбца проверьте, имеет ли он последовательность

select pg_get_serial_sequence('<table_name>', '<column_name>')

и затем, получить информацию об этой последовательности

select * from <sequence_name>

связь между автоматически генерируемыми последовательностями ( например, созданными для последовательных столбцов ) и родительской таблицей моделируется атрибутом владельца последовательности.

вы можете изменить это отношение, используя предложение OWNED BY изменить последовательность commmand

например, ALTER SEQUENCE foo_id принадлежит foo_schema.foo_table

чтобы установить связь с таблицей foo_table

или Изменить foo_id последовательности Не принадлежит никому

чтобы разорвать связь между последовательностью и любой таблицей

информация об этой связи хранится в таблица каталога pg_depend.

связь соединения-это связь между pg_depend.objid - > pg_class.oid, где relkind = 'S' - который связывает последовательность с записью соединения, а затем pg_depend.refobjid - > pg_class.oid, где relkind = 'r', который связывает запись соединения с отношением владения ( таблица )

этот запрос возвращает все зависимости sequence - > table в базе данных. Предложение where фильтрует его только для включения автоматически созданных связей,что ограничивает его только отображением последовательностей, созданных столбцами с последовательным типом.

WITH fq_objects AS (SELECT c.oid,n.nspname || '.' ||c.relname AS fqname , 
                           c.relkind, c.relname AS relation 
                    FROM pg_class c JOIN pg_namespace n ON n.oid = c.relnamespace ),

     sequences AS (SELECT oid,fqname FROM fq_objects WHERE relkind = 'S'),  
     tables    AS (SELECT oid, fqname FROM fq_objects WHERE relkind = 'r' )  
SELECT
       s.fqname AS sequence, 
       '->' as depends, 
       t.fqname AS table 
FROM 
     pg_depend d JOIN sequences s ON s.oid = d.objid  
                 JOIN tables t ON t.oid = d.refobjid  
WHERE 
     d.deptype = 'a' ;

информация о последовательности: максимальное значение

SELECT * FROM information_schema.sequences;

информация о последовательности: последнее значение

SELECT * FROM <sequence_name>


частично проверял, но выглядит в основном завершена.

select *
  from (select n.nspname,c.relname,
               (select substring(pg_catalog.pg_get_expr(d.adbin, d.adrelid) for 128)
                  from pg_catalog.pg_attrdef d
                 where d.adrelid=a.attrelid
                   and d.adnum=a.attnum
                   and a.atthasdef) as def
          from pg_class c, pg_attribute a, pg_namespace n
         where c.relkind='r'
           and c.oid=a.attrelid
           and n.oid=c.relnamespace
           and a.atthasdef
           and a.atttypid=20) x
 where x.def ~ '^nextval'
 order by nspname,relname;

должное... он частично реверсивно спроектирован из SQL, зарегистрированного из A \d в известной таблице, которая имела последовательность. Я уверен, что это может быть чище, но эй, производительность не была проблемой.


Я знаю, что этот пост довольно старый, но я нашел решение CMS быть очень полезным, поскольку я искал автоматический способ связать последовательность с таблицей и столбцом и хотел поделиться. Использование pg_depend таблица каталога была ключом. Я расширил то, что было сделано:

WITH fq_objects AS (SELECT c.oid,n.nspname || '.' ||c.relname AS fqname ,
                           c.relkind, c.relname AS relation
                    FROM pg_class c JOIN pg_namespace n ON n.oid = c.relnamespace ),

     sequences AS (SELECT oid,fqname FROM fq_objects WHERE relkind = 'S'),
     tables    AS (SELECT oid, fqname FROM fq_objects WHERE relkind = 'r' )
SELECT
       s.fqname AS sequence,
       '->' as depends,
       t.fqname AS table,
       a.attname AS column
FROM
     pg_depend d JOIN sequences s ON s.oid = d.objid
                 JOIN tables t ON t.oid = d.refobjid
                 JOIN pg_attribute a ON a.attrelid = d.refobjid and a.attnum = d.refobjsubid
WHERE
     d.deptype = 'a' ;

эта версия добавляет столбец в список возвращаемых полей. С именем таблицы и именем столбца в руке вызов pg_set_serial_sequence легко убедиться, что все последовательности в базе данных установлены правильно. Например:

CREATE OR REPLACE FUNCTION public.reset_sequence(tablename text, columnname text)
 RETURNS void
 LANGUAGE plpgsql
AS $function$
DECLARE
    _sql VARCHAR := '';
BEGIN
    _sql := $$SELECT setval( pg_get_serial_sequence('$$ || tablename || $$', '$$ || columnname || $$'), (SELECT COALESCE(MAX($$ || columnname || $$),1) FROM $$ || tablename || $$), true)$$;
    EXECUTE _sql;
END;
$function$;

надеюсь, это поможет кому-то сбросить последовательности!


улучшение предыдущего ответа:

select string_agg('select sequence_name, last_value from ' || relname, chr(13) || 'union' || chr(13) order by relname) 
from pg_class where relkind ='S'

вид взлома, но попробуйте это:

выберите "Выбрать" | | relname | | "'как последовательность, last_value из' | / relname | / 'union' Из pg_catalog.pg_class c Где c.relkind IN ('S',");

удалите последнее объединение и выполните результат


в этом операторе перечислены таблица и столбец, связанные с каждой последовательностью:

код:

    SELECT t.relname as related_table, 
           a.attname as related_column,
           s.relname as sequence_name
    FROM pg_class s 
      JOIN pg_depend d ON d.objid = s.oid 
      JOIN pg_class t ON d.objid = s.oid AND d.refobjid = t.oid 
      JOIN pg_attribute a ON (d.refobjid, d.refobjsubid) = (a.attrelid, a.attnum)
      JOIN pg_namespace n ON n.oid = s.relnamespace 
    WHERE s.relkind     = 'S' 

  AND n.nspname     = 'public'

Подробнее см. здесь ссылка на ответ


Спасибо за помощь.

вот функция pl/pgsql, которая обновляет каждую последовательность базы данных.

---------------------------------------------------------------------------------------------------------
--- Nom : reset_sequence
--- Description : Générique - met à jour les séquences au max de l'identifiant
---------------------------------------------------------------------------------------------------------

CREATE OR REPLACE FUNCTION reset_sequence() RETURNS void AS 
$BODY$
DECLARE _sql VARCHAR := '';
DECLARE result threecol%rowtype; 
BEGIN
FOR result IN 
WITH fq_objects AS (SELECT c.oid,n.nspname || '.' ||c.relname AS fqname ,c.relkind, c.relname AS relation FROM pg_class c JOIN pg_namespace n ON n.oid = c.relnamespace ),
    sequences AS (SELECT oid,fqname FROM fq_objects WHERE relkind = 'S'),
    tables    AS (SELECT oid, fqname FROM fq_objects WHERE relkind = 'r' )
SELECT
       s.fqname AS sequence,
       t.fqname AS table,
       a.attname AS column
FROM
     pg_depend d JOIN sequences s ON s.oid = d.objid
                 JOIN tables t ON t.oid = d.refobjid
                 JOIN pg_attribute a ON a.attrelid = d.refobjid and a.attnum = d.refobjsubid
WHERE
     d.deptype = 'a' 
LOOP
     EXECUTE 'SELECT setval('''||result.col1||''', COALESCE((SELECT MAX('||result.col3||')+1 FROM '||result.col2||'), 1), false);';
END LOOP;
END;$BODY$ LANGUAGE plpgsql;

SELECT * FROM reset_sequence();

вот еще один, который имеет название схемы рядом с именем последовательности

select nspname,relname from pg_class c join pg_namespace n on c.relnamespace=n.oid where relkind = 'S' order by nspname

получить последовательности по каждому столбцу каждой таблицы с помощью синтаксического анализа предложения по умолчанию. Этот метод обеспечивает информация о том, с какими последовательностями столбцов связаны и не использовать зависимости что может не существовать для некоторых последовательностей. Даже