获取所有具有当前值的序列
Get all sequences with current values
我有以下获取所有序列及其模式的查询:
SELECT sequence_schema as schema, sequence_name as sequence
FROM information_schema.sequences
WHERE sequence_schema NOT IN ('topology', 'tiger')
ORDER BY 1, 2
我想用 select last_value from [sequence];
之类的东西获取每个序列名称的当前值。我尝试了以下方法(以及一些变体),但它不起作用,因为语法不正确:
DO $$
BEGIN
EXECUTE
sequence_schema as schema,
sequence_name as sequence,
last_value
FROM information_schema.sequences
LEFT JOIN (
EXECUTE 'SELECT last_value FROM ' || schema || '.' || sequence
) tmp
ORDER BY 1, 2;
END
$$;
我找到了一些创建函数来执行文本或在函数内拼凑查询和 return 结果的解决方案,但我更希望有一个我可以 运行 随心所欲地修改。
你可以依赖函数pg_sequence_last_value
SELECT nspname as schema,
relname AS sequence_name,
coalesce(pg_sequence_last_value(s.oid), 0) AS seq_last_value
FROM pg_class AS s
JOIN pg_depend AS d ON d.objid = s.oid
JOIN pg_attribute a ON d.refobjid = a.attrelid
AND d.refobjsubid = a.attnum
JOIN pg_namespace nsp ON s.relnamespace = nsp.oid
WHERE s.relkind = 'S'
AND d.refclassid = 'pg_class'::regclass
AND d.classid = 'pg_class'::regclass
AND nspname NOT IN ('topology', 'tiger')
ORDER BY 1,2 DESC;
在 Postgres 12 中,您可以使用 pg_sequences
:
select schemaname as schema,
sequencename as sequence,
last_value
from pg_sequences
这是一个不依赖于 pg_sequences
或 pg_sequence_last_value
的解决方案:
CREATE OR REPLACE FUNCTION get_sequences()
RETURNS TABLE (
last_value bigint,
sequence_schema text,
sequence_name text
)
LANGUAGE plpgsql AS
$func$
DECLARE
s RECORD;
BEGIN
FOR s IN SELECT t.sequence_schema, t.sequence_name
FROM information_schema.sequences t
LOOP
RETURN QUERY EXECUTE format(
'SELECT last_value, ''%1$s''::text, ''%2$s''::text FROM %1$I.%2$I',
s.sequence_schema,
s.sequence_name
);
END LOOP;
END;
$func$;
SELECT * FROM get_sequences();
这将输出一个 table 像这样:
last_value | sequence_schema | sequence_name
------------+-----------------+-------------------------------------------------------
1 | public | contact_infos_id_seq
1 | media | photos_id_seq
2006 | company | companies_id_seq
2505 | public | houses_id_seq
1 | public | purchase_numbers_id_seq
... etc
其他答案只有在您使用现代版本的 Postgres(我相信 10 或更高版本)时才有效。
我有以下获取所有序列及其模式的查询:
SELECT sequence_schema as schema, sequence_name as sequence
FROM information_schema.sequences
WHERE sequence_schema NOT IN ('topology', 'tiger')
ORDER BY 1, 2
我想用 select last_value from [sequence];
之类的东西获取每个序列名称的当前值。我尝试了以下方法(以及一些变体),但它不起作用,因为语法不正确:
DO $$
BEGIN
EXECUTE
sequence_schema as schema,
sequence_name as sequence,
last_value
FROM information_schema.sequences
LEFT JOIN (
EXECUTE 'SELECT last_value FROM ' || schema || '.' || sequence
) tmp
ORDER BY 1, 2;
END
$$;
我找到了一些创建函数来执行文本或在函数内拼凑查询和 return 结果的解决方案,但我更希望有一个我可以 运行 随心所欲地修改。
你可以依赖函数pg_sequence_last_value
SELECT nspname as schema,
relname AS sequence_name,
coalesce(pg_sequence_last_value(s.oid), 0) AS seq_last_value
FROM pg_class AS s
JOIN pg_depend AS d ON d.objid = s.oid
JOIN pg_attribute a ON d.refobjid = a.attrelid
AND d.refobjsubid = a.attnum
JOIN pg_namespace nsp ON s.relnamespace = nsp.oid
WHERE s.relkind = 'S'
AND d.refclassid = 'pg_class'::regclass
AND d.classid = 'pg_class'::regclass
AND nspname NOT IN ('topology', 'tiger')
ORDER BY 1,2 DESC;
在 Postgres 12 中,您可以使用 pg_sequences
:
select schemaname as schema,
sequencename as sequence,
last_value
from pg_sequences
这是一个不依赖于 pg_sequences
或 pg_sequence_last_value
的解决方案:
CREATE OR REPLACE FUNCTION get_sequences()
RETURNS TABLE (
last_value bigint,
sequence_schema text,
sequence_name text
)
LANGUAGE plpgsql AS
$func$
DECLARE
s RECORD;
BEGIN
FOR s IN SELECT t.sequence_schema, t.sequence_name
FROM information_schema.sequences t
LOOP
RETURN QUERY EXECUTE format(
'SELECT last_value, ''%1$s''::text, ''%2$s''::text FROM %1$I.%2$I',
s.sequence_schema,
s.sequence_name
);
END LOOP;
END;
$func$;
SELECT * FROM get_sequences();
这将输出一个 table 像这样:
last_value | sequence_schema | sequence_name
------------+-----------------+-------------------------------------------------------
1 | public | contact_infos_id_seq
1 | media | photos_id_seq
2006 | company | companies_id_seq
2505 | public | houses_id_seq
1 | public | purchase_numbers_id_seq
... etc
其他答案只有在您使用现代版本的 Postgres(我相信 10 或更高版本)时才有效。