web-dev-qa-db-fra.com

Comment répertorier toutes les colonnes d'une table spécifiée

Je recherche une information précise dans une base de données dont je n'ai aucune connaissance.

C'est un produit tiers, ils sont lents à répondre à certaines questions, et je sais que les données se trouvent à l'intérieur de cette base de données, donc je veux faire un peu d'ingénierie rétro.

Étant donné une table, est-il possible d'avoir une liste des noms des colonnes de cette table?

Par exemple, dans SqlServer, il est possible de vider une table dans une instruction CREATE réutilisable, qui répertorie textuellement toutes les colonnes de la table.

321
Stephane Rolland

En plus de la ligne de commande \d+ <table_name> que vous avez déjà trouvé, vous pouvez également utiliser le schéma d'information pour rechercher les données de la colonne, en utilisant information_schema.columns :

SELECT *
  FROM information_schema.columns
 WHERE table_schema = 'your_schema'
   AND table_name   = 'your_table'
     ;

Remarque: Comme dans l'exemple ci-dessus, assurez-vous que les valeurs sont placées entre guillemets.

384
bhamby

En complément des autres réponses, même une instruction SELECT qui ne renvoie aucune ligne vous exposera les noms des colonnes et le code de l'application.

select *
from table_name
where false;

Les autorisations peuvent entrer en jeu avec l'une de ces approches.

Le schéma d'information est le moyen lent et sûr: il est normalisé et largement portable sur les autres bases de données qui le prennent en charge. Et il continuera de fonctionner sur les principales versions.

Cependant, les vues du schéma d'information se joignent souvent à de nombreuses tables des catalogues système pour respecter un format strictement standardisé - dont beaucoup ne sont que du fret mort la plupart du temps. Cela les rend lents .
Les développeurs de Postgres ne font pas de promesses, mais les bases (comme ce qui est nécessaire ici) ne changeront pas entre les principales versions.

psql (l'interface de ligne de commande native) prend la voie rapide, bien sûr, et interroge directement la source. Si vous commencez psql avec le paramètre -E , le SQL derrière les commandes antislash comme \d est affiché. Ou \set ECHO_HIDDEN on à partir de la ligne de commande psql. À partir de là, vous pouvez construire une réponse à votre question.

Étant donné une table, est-il possible d'avoir une liste des noms des colonnes de cette table.

SELECT attrelid::regclass AS tbl
     , attname            AS col
     , atttypid::regtype  AS datatype
       -- more attributes?
FROM   pg_attribute
WHERE  attrelid = 'myschema.mytable'::regclass  -- table name, optionally schema-qualified
AND    attnum > 0
AND    NOT attisdropped
ORDER  BY attnum;

Plus rapide que interrogation de information_schema.columns . Essayez EXPLAIN ANALYZE pour voir par vous-même. Peu importe encore pour une recherche unique. Mais cela peut faire une différence s'il est utilisé dans une requête/fonction répétée plusieurs fois.

Il existe également de subtiles différences de visibilité. Comparaison détaillée:

76
Erwin Brandstetter

psql sur PostgreSQL 11+

Si vous recherchez les types de colonnes dans une requête, vous pouvez utiliser psql's \gdesc

SELECT
    NULL AS zero,
    1 AS one,
    2.0 AS two,
    'three' AS three,
    $1 AS four,
    sin($2) as five,
    'foo'::varchar(4) as six,
    CURRENT_DATE AS now
\gdesc
 Column |         Type         
--------+----------------------
 zero   | text
 one    | integer
 two    | numeric
 three  | text
 four   | text
 five   | double precision
 six    | character varying(4)
 now    | date
(8 rows)
8
Evan Carroll

PostgreSQL uniquement

C'est un peu hokey mais pourrait être un concurrent si vous recherchez le SQL le plus court possible:

SELECT json_object_keys(to_json(json_populate_record(NULL::schema_name.table_name, '{}'::JSON)))

ou même plus court (en supposant qu'il y ait au moins une ligne présente dans le tableau)

SELECT json_object_keys(to_json((SELECT t FROM schema_name.table_name t LIMIT 1)))

La liste préserve la commande. Si vous ne vous souciez pas de la commande et que l'extension hstore est installée, vous pouvez faire encore plus court

SELECT skeys(hstore(NULL::schema_name.table_name))
0
oᴉɹǝɥɔ