我正在将一个db从postgres转换为mysql。
由于我找不到一个可以自行完成技巧的工具,我将使用自动增量值将所有postgres序列转换为mysql中的自动增量id。
那么,我如何在 Postgres 数据库( 8.1 版本)中列出所有序列,其中包含有关使用它的表的信息,下一个值等等SQL查询?
请注意,我无法使用8.4版本中的information_schema.sequences
视图。
答案 0 :(得分:195)
以下查询提供所有序列的名称。
SELECT c.relname FROM pg_class c WHERE c.relkind = 'S';
通常,序列命名为${table}_id_seq
。简单的正则表达式模式匹配将为您提供表名。
要获取序列的最后一个值,请使用以下查询:
SELECT last_value FROM test_id_seq;
答案 1 :(得分:54)
请注意,从PostgreSQL 8.4开始,您可以通过以下方式获取有关数据库中使用的序列的所有信息:
SELECT * FROM information_schema.sequences;
由于我使用的是更高版本的PostgreSQL(9.1),并且正在寻找相同的答案,我为后人和未来的搜索者添加了这个答案。
答案 2 :(得分:51)
运行:psql -E
,然后\ds
答案 3 :(得分:24)
实现这一目标的最佳方法是列出所有表格
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>
答案 4 :(得分:10)
自动生成的序列(例如为SERIAL列创建的序列)与父表之间的关系由序列所有者属性建模。
的OWNED BY子句修改此关系e.g。 由foo_schema.foo_table提供的更新序列foo_id
将其设置为链接到表foo_table
或 ALTER SEQUENCE foo_id拥有NONE
打破序列与任何表之间的连接
有关此关系的信息存储在pg_depend catalogue table中。
加入关系是pg_depend.objid - &gt;之间的链接。 pg_class.oid WHERE relkind ='S' - 将序列链接到连接记录,然后是pg_depend.refobjid - &gt; pg_class.oid WHERE relkind ='r',它将连接记录链接到拥有关系(表)
此查询返回所有序列 - &gt;数据库中的表依赖项。 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' ;
答案 5 :(得分:8)
序列信息:最大值
SELECT * FROM information_schema.sequences;
序列信息:最后一个值
SELECT * FROM <sequence_name>
答案 6 :(得分:3)
我知道问题是关于postgresql版本8的,但是我在这里为想要获取版本10和更高版本中的序列的人写了这种简单的方法
您可以使用以下查询
select * from pg_sequences
答案 7 :(得分:3)
我知道这篇文章很老了,但我发现CMS的解决方案非常有用,因为我正在寻找一种自动方式将序列链接到表AND列,并想分享。使用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$;
希望这有助于重置序列的人!
答案 8 :(得分:1)
改进上一个答案:
select string_agg('select sequence_name, last_value from ' || relname, chr(13) || 'union' || chr(13) order by relname)
from pg_class where relkind ='S'
答案 9 :(得分:1)
此语句列出与每个序列关联的表和列:
代码:
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'
更多信息请见link to answer
答案 10 :(得分:1)
有点黑客,但试试这个:
选择'select'''|| relname || '''作为序列,来自'||的last_value relname || '工会' 来自pg_catalog.pg_class c 在哪里c.relkind IN('S','');
删除最后一个UNION并执行结果
答案 11 :(得分:1)
部分测试但看起来大部分都是完整的。
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;
信用到期的信用......它部分是从具有序列的已知表上的\ d记录的SQL中进行逆向工程的。我相信它也可以更干净,但是嘿,性能不是一个问题。
答案 12 :(得分:0)
感谢您的帮助。
这是pl / pgsql函数,它更新数据库的每个序列。
allocator_type m_alloc; // Should probably be private
Container( size_type n =0 , const allocator_type& allocator =allocator_type() ) :
m_alloc{allocator}{
std::cout << "ctor" << std::endl;
m_alloc.allocate(n);
};
答案 13 :(得分:0)
这是另一个在序列名称旁边具有模式名称的文件名
select nspname,relname from pg_class c join pg_namespace n on c.relnamespace=n.oid where relkind = 'S' order by nspname
答案 14 :(得分:0)
通过解析DEFAULT子句按每个表的每个列获取序列。此方法提供有关链接到哪些列序列的信息,并且不使用dependencies,对于某些序列可能不存在。甚至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个序列可以在多个表中使用,因此可以在这里在多行中列出。
答案 15 :(得分:0)
此函数显示每个序列的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();
答案 16 :(得分:0)
假设此帖子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
答案 17 :(得分:0)
select sequence_name, (xpath('/row/last_value/text()', xml_count))[1]::text::int as last_value
from (
select sequence_schema,
sequence_name,
query_to_xml(format('select last_value from %I.%I', sequence_schema, sequence_name), false, true, '') as xml_count
from information_schema.sequences
where sequence_schema = 'public'
) new_table order by last_value desc;
答案 18 :(得分:0)
这里是一个示例,说明如何使用psql
来获取所有序列及其last_value
的列表:
psql -U <username> -d <database> -t -c "SELECT 'SELECT ''' || c.relname || ''' as sequence_name, last_value FROM ' || c.relname || ';' FROM pg_class c WHERE (c.relkind = 'S')" | psql -U <username> -d <database> -t