列出所有列在Postgres db8.1SQL
-
18-09-2019 - |
题
我是转换一个数据库从postgres to mysql.
因为我找不到一个工具,不会欺骗自己,我会把所有postgres序,以自动增量ids in mysql与自动增量值。
所以,我怎么可以列出所有的序列中的一个 Postgres DB(8.1 版本)有关的信息表在其它的使用,未来价值等SQL query?
要知道,我不能使用 information_schema.sequences
看在8.4释放。
解决方案
下面的查询给出了所有序列的名称。
SELECT c.relname FROM pg_class c WHERE c.relkind = 'S';
典型地,序列被命名为${table}_id_seq
。简单的regex模式匹配会给你的表名。
要得到的序列的最后一个值使用以下查询:
SELECT last_value FROM test_id_seq;
其他提示
请注意,从8.4的PostgreSQL开始就可以得到所有关于通过在数据库中使用的序列信息:
SELECT * FROM information_schema.sequences;
由于我使用的是更高版本的PostgreSQL(9.1),并寻找相同的答案高低,我说这个答案留给后人的缘故,并为未来的搜索。
执行命令psql -E
,然后\ds
疼痛的一点点后,我得到它。
实现这一目标的最佳方式是列出所有表
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>
自动生成的序列(例如用于SERIAL列创建)和父表之间的关系是由序列所有者属性建模。
可以使用所拥有的 ALTER SEQUENCE修改此关系条命令
e.g。 ALTER SEQUENCE foo_id通过foo_schema.foo_table国有
将其设置为被链接到表格foo_table
或 ALTER SEQUENCE foo_id通过NONE国有
打破序列和任何表之间的连接
关于该关系的信息被存储在 pg_depend目录表。
的接合关系是pg_depend.objid之间的链路 - > WHERE pg_class.oid = relkind 'S' - 其中序列链接到加入记录,然后pg_depend.refobjid - > WHERE pg_class.oid = relkind 'R',一个把该连接记录所属关系(表)
这个查询返回所有的序列 - >在数据库表中的依赖关系。 where子句它过滤为仅包括自动生成的关系,这会限制由SERIAL类型列创建仅显示序列。
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>
我知道这个职位是很老,但我发现 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 *
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工程从\ d登录一个已知的表有一个序列。我敢肯定,这可能是更清洁过,但是,嘿,性能是不是一个问题。
一劈的种类,但尝试:
选择 '选择 ''' || relname || “”“如序列,从LAST_VALUE” || relname || “联盟” 从pg_catalog.pg_classÇ 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'
更多的在这里看到的 链接的答案
经由DEFAULT子句的解析每个表的每列中获取序列。此方法提供的即将哪一列序列被连接强>信息,并且不使用依赖性其可以不存在一些序列。即使pg_get_serial_sequence(sch.nspname||'.'||tbl.relname, col.attname)
功能发现的不是所有的我的序列!
解决方案:
SELECT
seq_sch.nspname AS sequence_schema
, seq.relname AS sequence_name
, seq_use."schema" AS used_in_schema
, seq_use."table" AS used_in_table
, seq_use."column" AS used_in_column
FROM pg_class seq
INNER JOIN pg_namespace seq_sch ON seq_sch.oid = seq.relnamespace
LEFT JOIN (
SELECT
sch.nspname AS "schema"
, tbl.relname AS "table"
, col.attname AS "column"
, regexp_split_to_array(
TRIM(LEADING 'nextval(''' FROM
TRIM(TRAILING '''::regclass)' FROM
pg_get_expr(def.adbin, tbl.oid, TRUE)
)
)
, '\.'
) AS column_sequence
FROM pg_class tbl --the table
INNER JOIN pg_namespace sch ON sch.oid = tbl.relnamespace
--schema
INNER JOIN pg_attribute col ON col.attrelid = tbl.oid
--columns
INNER JOIN pg_attrdef def ON (def.adrelid = tbl.oid AND def.adnum = col.attnum) --default values for columns
WHERE tbl.relkind = 'r' --regular relations (tables) only
AND col.attnum > 0 --regular columns only
AND def.adsrc LIKE 'nextval(%)' --sequences only
) seq_use ON (seq_use.column_sequence [1] = seq_sch.nspname AND seq_use.column_sequence [2] = seq.relname)
WHERE seq.relkind = 'S' --sequences only
ORDER BY sequence_schema, sequence_name;
请注意1个序列可以在多个表中被使用,所以它可以在这里多行中列出。
感谢您的帮助。
下面是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
此功能显示每个序列的LAST_VALUE。
它输出一个2列的表,该序列名称说再加上它的最后生成的值。
drop function if exists public.show_sequence_stats();
CREATE OR REPLACE FUNCTION public.show_sequence_stats()
RETURNS TABLE(tablename text, last_value bigint)
LANGUAGE 'plpgsql'
COST 100
VOLATILE
ROWS 1000
AS $BODY$
declare r refcursor; rec record; dynamic_query varchar;
BEGIN
dynamic_query='select tablename,last_value from (';
open r for execute 'select nspname,relname from pg_class c join pg_namespace n on c.relnamespace=n.oid where relkind = ''S'' order by nspname';
fetch next from r into rec;
while found
loop
dynamic_query=dynamic_query || 'select '''|| rec.nspname || '.' || rec.relname ||''' "tablename",last_value from ' || rec.nspname || '.' || rec.relname || ' union all ';
fetch next from r into rec;
end loop;
close r;
dynamic_query=rtrim(dynamic_query,'union all') || ') x order by last_value desc;';
return query execute dynamic_query;
END;
$BODY$;
select * from show_sequence_stats();
假设在此篇 https://stackoverflow.com/a/46721603/653539 时,序列声明一起exec()
功能与他们的最后值可使用单个查询中获取:
select s.sequence_schema, s.sequence_name,
(select * from exec('select last_value from ' || s.sequence_schema || '.' || s.sequence_name) as e(lv bigint)) last_value
from information_schema.sequences s