列出 PostgreSQL 中模式的所有非生成序列

发布于 2024-10-27 12:18:15 字数 277 浏览 2 评论 0原文

在 PostgreSQL 中,有两种类型的序列:

  • 用户使用 CREATE SEQUENCE 创建的序列
  • 由数据库生成的序列,用于支持 SERIAL

INFORMATION_SCHEMA 类型的列。SEQUENCES 返回两种类型的序列。

什么SQL语句可以获取特定模式的用户创建的序列列表(不包括数据库生成的序列)?

PS:我使用的是 PostgreSQL 9

In PostgreSQL there are 2 types of sequences:

  • Sequences created by the user using CREATE SEQUENCE
  • Sequences generated by the DB to back a column of type SERIAL

INFORMATION_SCHEMA.SEQUENCES returns both types of sequences.

What SQL statement can get a list of the sequences created by the user (WITHOUT the ones generated by the DB) for a specific schema?

P.S.: I'm using PostgreSQL 9

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

你与昨日 2024-11-03 12:18:15

对于生成的序列,将自动定义“拥有”列,以便可以成为区分因素。

但这也可以手动完成,因此无法区分:

create table foo (
   id_col serial not null
);

create table foo (
   id_col integer not null
);
create sequence foo_id_col_seq owned by foo.id_col;

但是,如果这对您来说没问题,则以下语句可以为您提供该信息:

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

您将通过该查询获得每个序列的至少一行:对创建该序列的架构的依赖关系。

对于由您所拥有的列所拥有的序列将得到另一行及其所属的表和列。

For a generated sequence the "owning" column will be defined automatically so that could be a distinguishing factor.

But that can be done manually as well, so there is no way to tell the difference between:

create table foo (
   id_col serial not null
);

and

create table foo (
   id_col integer not null
);
create sequence foo_id_col_seq owned by foo.id_col;

But if that is OK for you, the following statement can get you that information:

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

You'll get at least one row for each sequence by that query: the dependency on the schema it was created in.

For a sequence owned by a column you'll get another row with the table and column it belongs to.

木森分化 2024-11-03 12:18:15

唯一的区别可能(至少)在于它的定义位置。输入 \d yourtable 会将修饰符列中的序列列为 nextval(...),但随后定义的序列则不会。 pg_catalog.attr_def 将数据保存到用于定义的实际字符串中。

我同意马的观点,即功能上没有区别。它类似于在一两行中声明某些内容,但会发生完全相同的事情。 数据库正在生成所有这些序列,并且没有用户序列。唯一的区别在于它们的声明方式以及保留此信息的唯一方式是定义列的实际字符串保存在系统目录中。

来自系统表:

create view check_seq as
SELECT a.attname,
    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 "column def"

FROM pg_catalog.pg_attribute a
join pg_catalog.pg_class c on a.attrelid = c.oid
WHERE a.attnum > 0 AND NOT a.attisdropped
and c.relname in ('foo')
ORDER BY a.attnum
;

示例:

create table foo (
   id_col serial not null
);
select * from check_seq;

 attname | relname |             column def           
 ---------+---------+-------------------------------------
  id_col  | foo     | nextval('foo_id_col_seq'::regclass)


drop table foo;
create table foo (
   id_col integer not null
);
create sequence foo_id_col_seq owned by foo.id_col;
select * from check_seq;

 attname | relname | column def
 ---------+---------+------------
  id_col  | foo     |

The only difference may (at the least) be where it is defined. Entering \d yourtable will list serials in the modifiers column as nextval(...), but sequences defined afterward will not. pg_catalog.attr_def holds data to the actual strings that were used for definition.

I agree with horse that functionally there is no difference. Its akin to declaring something on one line or two but the same exact things happens. The DB is generating all these sequences and there is no user sequences. The only difference is in how they are declared and the only way this information is persisted is the actual strings that defined the column are held in the system catalogs.

From the system tables:

create view check_seq as
SELECT a.attname,
    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 "column def"

FROM pg_catalog.pg_attribute a
join pg_catalog.pg_class c on a.attrelid = c.oid
WHERE a.attnum > 0 AND NOT a.attisdropped
and c.relname in ('foo')
ORDER BY a.attnum
;

Examples:

create table foo (
   id_col serial not null
);
select * from check_seq;

 attname | relname |             column def           
 ---------+---------+-------------------------------------
  id_col  | foo     | nextval('foo_id_col_seq'::regclass)


drop table foo;
create table foo (
   id_col integer not null
);
create sequence foo_id_col_seq owned by foo.id_col;
select * from check_seq;

 attname | relname | column def
 ---------+---------+------------
  id_col  | foo     |
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文