使用SQL列出Postgres数据库8.1中的所有序列
我正在将数据库从Postgres转换为MySQL。
由于我找不到一个工具,自己动手,我要将所有postgres序列转换为mysql中的自动增量id和自动增量值。
那么,如何在Postgres数据库( 8.1版本)中列出所有序列,并使用SQL查询使用的表格,下一个值等信息?
请注意,我无法使用8.4版本中的information_schema.sequences
视图。
以下查询给出了所有序列的名称。
SELECT c.relname FROM pg_class c WHERE c.relkind = 'S';
通常一个序列被命名为${table}_id_seq
。 简单的正则expression式模式匹配会给你表名。
要获取序列的最后一个值,请使用以下查询:
SELECT last_value FROM test_id_seq;
运行: psql -E
,然后运行\ds
请注意,从PostgreSQL 8.4开始,您可以通过以下方式获取有关数据库中使用的序列的所有信息:
SELECT * FROM information_schema.sequences;
由于我使用的是更高版本的PostgreSQL(9.1),并且正在寻找相同的答案,所以我为了后人和未来的search者而添加了这个答案。
一点点痛苦之后,我明白了。
最好的办法是列出所有的表格
select * from pg_tables where schemaname = '<schema_name>'
然后,对于每个表,列出具有属性的所有列
select * from information_schema.columns where table_name = '<table_name>'
然后,对于每一列,testing它是否有一个序列
select pg_get_serial_sequence('<table_name>', '<column_name>')
然后获取关于这个序列的信息
select * from <sequence_name>
自动生成的序列(例如为SERIAL列创build的序列)和父表之间的关系由序列所有者属性build模。
您可以使用ALTER SEQUENCE命令的OWNED BY子句修改此关系
例如,由foo_schema.foo_table拥有的ALTER SEQUENCE foo_id
将其设置为链接到表foo_table
或ALTER SEQUENCE foo_id由NONE所有
打破序列和任何表之间的连接
有关这种关系的信息存储在pg_depend目录表中 。
join关系是pg_depend.objid – > pg_class.oid WHERE relkind ='S'之间的链接 – 将序列链接到连接logging,然后pg_depend.refobjid – > pg_class.oid WHERE relkind ='r',链接joinlogging到拥有关系(表)
该查询返回数据库中的所有序列 – >表依赖关系。 where子句将其过滤为仅包含自动生成的关系,从而将其限制为仅显示由SERIALtypes列创build的序列。
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>
部分testing,但看起来大部分完成。
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;
信用在哪里到期…它的部分反向工程从logging从一个已知的表有一个序列\ d的SQL。 我相信它也可以更干净,但是,嘿,performance不是一个问题。
我知道这篇文章是相当古老,但我发现由CMS的解决scheme是非常有用的,因为我正在寻找一种自动的方式链接到表和列的序列,并希望分享。 关键是使用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'select'''|| relname || '''作为序列,来自'||的last_value relname || 'union'FROM pg_catalog.pg_class c WHERE c.relkind IN('S','');
删除最后一个UNION并执行结果
先前答案的改进:
select string_agg('select sequence_name, last_value from ' || relname, chr(13) || 'union' || chr(13) order by relname) from pg_class where relkind ='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();