3

PostgreSQL には 2 種類のシーケンスがあります。

  • ユーザーが CREATE SEQUENCE を使用して作成したシーケンス
  • タイプSERIALの列をバックアップするためにDBによって生成されたシーケンス

INFORMATION_SCHEMA.SEQUENCES は、両方のタイプのシーケンスを返します。

特定のスキーマに対してユーザーが作成したシーケンスのリスト(DB によって生成されたものを除く) を取得できるSQL ステートメントはどれですか?

PS: PostgreSQL 9 を使用しています

4

2 に答える 2

5

生成されたシーケンスの場合、「所有」列が自動的に定義されるため、それが際立った要因になる可能性があります。

ただし、これは手動でも行うことができるため、次の違いを見分ける方法はありません。

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';

そのクエリによって、シーケンスごとに少なくとも 1 つの行が取得されます。つまり、それが作成されたスキーマへの依存関係です。

列が所有するシーケンスの場合、それが属するテーブルと列を含む別の行が取得されます。

于 2011-03-26T15:33:26.947 に答える
0

唯一の違いは、(少なくとも)定義されている場所です。入力\d yourtableすると、修飾子列にシリアルが nextval(...) としてリストされますが、後で定義されたシーケンスはリストされません。pg_catalog.attr_def定義に使用された実際の文字列にデータを保持します。

機能的には違いがないという馬に同意します。1 行または 2 行で何かを宣言するのと似ていますが、まったく同じことが起こります。DB はこれらすべてのシーケンスを生成しており、ユーザー シーケンスはありません。唯一の違いは宣言方法であり、この情報が永続化される唯一の方法は、列を定義した実際の文字列がシステム カタログに保持されることです。

システム テーブルから:

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     |
于 2011-03-28T03:34:47.830 に答える