카탈로그를 기반으로하는 정수 대신 열이 직렬 데이터 형식으로 정의되어 있는지 어떻게 확인합니까?


9

그래서 현재 테이블 정의를 빌드하기 위해 postgres (9.1) 카탈로그를 읽는 SQL을 만들고 있습니다. 그러나 SERIAL / BIGSERIAL 데이터 형식에 문제가 있습니다.

예:

CREATE TABLE cruft.temp ( id BIGSERIAL PRIMARY KEY );
SELECT * FROM information_schema.columns WHERE table_schema='cruft' AND table_name='temp';
"db","cruft","temp","id",1,"nextval('cruft.temp_id_seq'::regclass)","NO","bigint",,,64,2,0,,,,,,,,,,,,,"db","pg_catalog","int8",,,,,"1","NO","NO",,,,,,,"NEVER",,"YES"

데이터베이스 이름 (db), 스키마 이름 (cruft), 테이블 이름 (temp), 열 이름 (id), 기본값 (nextval (...)) 및 데이터 유형 (bigint 및 int8 .. NOT bigserial) ... 나는 기본값이 시퀀스인지 확인할 수 있다는 것을 알고 있지만 수동으로 시퀀스를 만들고 기본값이있는 비 연속 열을 만들 수 있기 때문에 100 % 정확하다고는 생각하지 않습니다. 그 순서.

누구든지 내가 이것을 성취 할 수있는 방법에 대한 제안이 있습니까? nextval (* _ seq)의 기본값을 확인하는 것 외에 다른 것이 있습니까?

TL; DR 또는 pg_catalog에 익숙하지 않은 신규 사용자의 경우 여기에 추가 된 SQL 솔루션 용으로 편집 :

with sequences as (
  select oid, relname as sequencename from pg_class where relkind = 'S'
) select
  sch.nspname as schemaname, tab.relname as tablename, col.attname as columnname, col.attnum as columnnumber, seqs.sequencename
from pg_attribute col
join pg_class tab on col.attrelid = tab.oid
join pg_namespace sch on tab.relnamespace = sch.oid
left join pg_attrdef def on tab.oid = def.adrelid and col.attnum = def.adnum
left join pg_depend deps on def.oid = deps.objid and deps.deptype = 'n'
left join sequences seqs on deps.refobjid = seqs.oid
where sch.nspname != 'information_schema' and sch.nspname not like 'pg_%' -- won't work if you have user schemas matching pg_
  and col.attnum > 0
  and seqs.sequencename is not null -- TO ONLY VIEW SERIAL/BIGSERIAL COLUMNS
order by sch.nspname, tab.relname, col.attnum;

1
나중에 코드 예제와 관련된 답변 : dba.stackexchange.com/questions/90555/…
Erwin Brandstetter

답변:


8

SERIALBIGSERIAL 은 일종의 의사 유형입니다. 알다시피, 실제로는 내부적으로 INTBIGINT 입니다.

뒤에서 일어나는 일은 PostgreSQL이 시퀀스를 생성하고 테이블에 대한 종속성을 설정한다는 것입니다. pg_class 에서 시퀀스 이름과 테이블과의 관계를 검색 할 수 있습니다 .

pg_class : http://www.postgresql.org/docs/9.2/static/catalog-pg-class.html

SQL 피들 : http://sqlfiddle.com/#!12/dfcbd/6

시퀀스 함수 : http://www.postgresql.org/docs/9.2/static/functions-sequence.html

이 StackOverflow 게시물이 도움이 될 수 있습니다 : /programming/1493262/list-all-sequences-in-a-postgres-db-8-1-with-sql

업데이트 : pg_depend 를 사용 하여 관심있는 테이블 / 열과 관련된 시퀀스를 알아낼 수 있습니다 : http://www.postgresql.org/docs/9.2/static/catalog-pg-depend.html


10

문서에 다음 내용이 포함되어 있다는 efesar의 답변에 추가하겠습니다.

smallserial, serial 및 bigserial 데이터 형식은 실제 형식이 아니라 고유 식별자 열을 만드는 데있어 표기법의 편의성입니다 (다른 데이터베이스에서 지원하는 AUTO_INCREMENT 속성과 유사). 현재 구현에서 다음을 지정하십시오.

CREATE TABLE tablename (
    colname SERIAL
);

다음을 지정하는 것과 같습니다.

CREATE SEQUENCE tablename_colname_seq;
CREATE TABLE tablename (
    colname integer NOT NULL DEFAULT nextval('tablename_colname_seq')
);
ALTER SEQUENCE tablename_colname_seq OWNED BY tablename.colname;

즉,

  • 열의 데이터 유형은 정수 (bigint)이며
  • NULL이 아니며
  • 기본값은 해당 열이 소유 한 시퀀스에서 나옵니다.

그런 다음 serial열입니다. 따라서 제안한대로 (을 추가하여 NOT NULL) 카탈로그에서 이러한 요소 를 확인하면 serial열 을 식별하기에 충분합니다 .

(큰) 시리얼을 찾기위한 실제 쿼리 는 Erwin Brandstetter 의 탁월한 답변 을 참조하십시오 .

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.