Je suis donc en train de créer du SQL pour lire les catalogues postgres (9.1) pour construire des définitions de table. Cependant, je rencontre un problème avec les types de données SERIAL / BIGSERIAL.
Exemple:
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"
Il me donne le nom de la base de données (db), le nom du schéma (cruft), le nom de la table (temp), le nom de la colonne (id), la valeur par défaut (nextval (...)) et le type de données (bigint et int8 .. PAS bigserial) ... Je me rends compte que je pouvais simplement vérifier si la valeur par défaut était une séquence - mais je ne pense pas que ce serait précis à 100% car je pourrais créer manuellement une séquence et créer une colonne non série où la valeur par défaut était cette séquence.
Quelqu'un at-il une suggestion sur la façon dont je pourrais accomplir cela? Autre chose que de vérifier la valeur par défaut pour un nextval (* _ seq)?
Modifié pour la solution SQL ajoutée ici en cas de TL; DR ou de nouveaux utilisateurs peu familiers avec le 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;
la source
Réponses:
SERIAL et BIGSERIAL sont des sortes de pseudo-types. Comme vous l'avez remarqué, ils ne sont vraiment que INT et BIGINT en interne.
Ce qui se passe dans les coulisses, c'est que PostgreSQL crée une séquence et configure une dépendance sur celle-ci à la table. Vous pouvez rechercher dans pg_class le nom de la séquence et sa relation avec la table.
pg_class: http://www.postgresql.org/docs/9.2/static/catalog-pg-class.html
SQL Fiddle: http://sqlfiddle.com/#!12/dfcbd/6
Fonctions de séquence: http://www.postgresql.org/docs/9.2/static/functions-sequence.html
Ce message StackOverflow peut être utile: /programming/1493262/list-all-sequences-in-a-postgres-db-8-1-with-sql
MISE À JOUR : Vous pouvez également utiliser pg_depend pour déterminer quelles séquences se rapportent à la table / colonne qui vous intéresse: http://www.postgresql.org/docs/9.2/static/catalog-pg-depend.html
la source
Permettez-moi d'ajouter à la réponse d'Efesar que la documentation indique ce qui suit:
Ce qui signifie que si
alors c'est une
serial
colonne. IlNOT NULL
suffit donc de vérifier ces facteurs dans les catalogues, comme vous l'avez proposé (avec l'ajout de ), pour identifier uneserial
colonne.Pour une requête réelle pour trouver les (grandes) séries, voir l' excellente réponse d'Erwin Brandstetter.
la source