Làm cách nào để xác định xem một cột được xác định là kiểu dữ liệu nối tiếp thay vì số nguyên dựa trên danh mục?


9

Vì vậy, tôi hiện đang tạo một số SQL để đọc qua các danh mục postgres (9.1) để xây dựng các định nghĩa bảng. Tuy nhiên, tôi gặp phải một vấn đề với các kiểu dữ liệu SERIAL / BIGSERIAL.

Thí dụ:

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"

Nó cung cấp cho tôi tên cơ sở dữ liệu (db), tên lược đồ (cruft), tên bảng (temp), tên cột (id), giá trị mặc định (nextval (...)) và loại dữ liệu (bigint và int8 .. KHÔNG bigserial) ... Tôi nhận ra rằng tôi chỉ có thể kiểm tra xem giá trị mặc định có phải là một chuỗi hay không - nhưng tôi không tin rằng nó sẽ chính xác 100% vì tôi có thể tự tạo một chuỗi và tạo một cột không nối tiếp trong đó giá trị mặc định là trình tự đó.

Có ai có một đề nghị cho làm thế nào tôi có thể thực hiện điều này? Bất cứ điều gì khác ngoài việc kiểm tra giá trị mặc định cho giá trị tiếp theo (* _ seq)?

Đã chỉnh sửa cho giải pháp SQL được thêm vào đây trong trường hợp TL; DR hoặc người dùng mới không quen thuộc với pg_catalog:

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
Sau đó, câu trả lời liên quan với các ví dụ mã: dba.stackexchange.com/questions/90555/ triệt
Erwin Brandstetter

Câu trả lời:


8

SERIALBIGSERIAL là loại giả. Như bạn nhận thấy, họ thực sự chỉ là INTBIGINT trong nội bộ.

Điều xảy ra đằng sau hậu trường là PostgreSQL tạo ra một chuỗi và thiết lập một sự phụ thuộc vào nó vào bảng. Bạn có thể tìm kiếm pg_group cho tên trình tự và cách nó liên quan đến bảng.

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

Câu đố về SQL: http://sqlfiddle.com/#!12/dfcbd/6

Hàm tuần tự: http://www.postgresql.org/docs/9.2/static/fifts- resultence.html

Bài đăng StackOverflow này có thể hữu ích: /programming/1493262/list-all- resultences-in-a-postgres-db-8-1-with-sql

CẬP NHẬT : Bạn cũng có thể sử dụng pg_depend để tìm ra chuỗi nào liên quan đến bảng / cột mà bạn quan tâm: http://www.postgresql.org/docs/9.2/static/catalog-pg-depend.html


10

Hãy để tôi thêm vào câu trả lời của efesar rằng tài liệu nêu rõ như sau:

Các kiểu dữ liệu smallserial, serial và bigserial không phải là kiểu đúng, mà chỉ là sự thuận tiện về mặt ký hiệu để tạo các cột định danh duy nhất (tương tự như thuộc tính AUTO_INCREMENT được hỗ trợ bởi một số cơ sở dữ liệu khác). Trong triển khai hiện tại, chỉ định:

CREATE TABLE tablename (
    colname SERIAL
);

tương đương với việc chỉ định:

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;

Có nghĩa là nếu

  • kiểu dữ liệu của một cột là số nguyên (bigint) và
  • nó không phải là NULL và
  • giá trị mặc định của nó xuất phát từ một chuỗi thuộc sở hữu của cột trong câu hỏi

sau đó nó là một serialcột. Vì vậy, kiểm tra các yếu tố này trong các danh mục, như bạn đề xuất (có thêm NOT NULL), là đủ để xác định một serialcột.

Đối với một truy vấn thực tế để tìm các sê-ri (lớn), hãy xem câu trả lời xuất sắc của Erwin Brandstetter.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.