Liste des clés primaires pour toutes les tables - Postgresql


14

Y a-t-il une requête qui fera cela?

J'ai trouvé quelques requêtes qui peuvent le faire pour une table, mais je n'ai pas pu le modifier pour que je puisse voir:

tablename | column | type

1
Si je posais cette question, j'aimerais connaître la position ordinale d'une colonne dans le PK (certains PK ont plus de 1 colonnes et l'ordre peut avoir de l'importance).
ypercubeᵀᴹ

Réponses:


13

Quelque chose comme ça:

select tc.table_schema, tc.table_name, kc.column_name
from information_schema.table_constraints tc
  join information_schema.key_column_usage kc 
    on kc.table_name = tc.table_name and kc.table_schema = tc.table_schema and kc.constraint_name = tc.constraint_name
where tc.constraint_type = 'PRIMARY KEY'
  and kc.ordinal_position is not null
order by tc.table_schema,
         tc.table_name,
         kc.position_in_unique_constraint;

Cette requête affiche non seulement les clés primaires mais aussi les index uniques
Michał Niklas

@ MichałNiklas ce n'est pas le cas.
dezso

1
@DarielPratama: la condition tc.constraint_type = 'PRIMARY KEY'n'affichera que les clés primaires. Cependant, chaque clé primaire est soutenue par un index unique
a_horse_with_no_name

2
@a_horse_with_no_name Je pense que c'est incorrect. position_in_unique_constraintindique la position de la clé FOREIGN, elle est toujours nulle pour les clés primaires. La colonne correcte est ordinal_position. Testé dans PG 9.4.
greatvovan

1
@a_horse_with_no_name J'ai approuvé une modification suggérée par un utilisateur anonyme. Vous ne savez pas si la modification sera effectuée, d'autres ont rejeté. Dans tous les cas, veuillez vérifier la suggestion et le commentaire ci-dessus de greatvovan. Je pense qu'ils sont corrects et ordinal_positiondevraient être utilisés. Le position_in_unique_constraintn'est pas nul uniquement dans l'utilisation des FK.
ypercubeᵀᴹ

20

C'est une réponse plus précise:

select tc.table_schema, tc.table_name, kc.column_name 
from  
    information_schema.table_constraints tc,  
    information_schema.key_column_usage kc  
where 
    tc.constraint_type = 'PRIMARY KEY' 
    and kc.table_name = tc.table_name and kc.table_schema = tc.table_schema
    and kc.constraint_name = tc.constraint_name
order by 1, 2;

Vous avez manqué la and kc.constraint_name = tc.constraint_namepartie, elle répertorie donc toutes les contraintes.


2
Pendant que votre requête fonctionne, la différence la plus importante est la and kc.position_in_unique_constraint is not nullpartie manquante . Et vous êtes fortement encouragé à utiliser les jointures ANSI (alors que beaucoup considèrent que c'est une question de goût).
dezso

1

Veuillez également considérer cela. Cela générera le script pour modifier toutes les tables.

SELECT STRING_AGG(FORMAT('ALTER TABLE %s CLUSTER ON %s;', A.table_name, A.constraint_name), E'\n') AS SCRIPT
FROM
(
    SELECT      FORMAT('%s.%s', table_schema, table_name) AS table_name, constraint_name
    FROM        information_schema.table_constraints
    WHERE       UPPER(constraint_type) = 'PRIMARY KEY'
    ORDER BY    table_name 
) AS A;

La question ne demande pas comment modifier les tables.
ypercubeᵀᴹ

1
J'appuie ce que dit @ ypercubeays. Supprimez cette réponse, mais ne vous découragez pas - faites le tour, visitez le centre d'aide et lisez le blog "Aidez-nous à vous aider". Quant à répondre à quelque chose qui n'a pas été demandé, nous l'avons tous fait plusieurs fois :-). ps bienvenue sur le forum!
Vérace

1

Je pense que pour obtenir la clé primaire et la clé étrangère devrait faire comme ça. kc.position_in_unique_constraint n'est pas nul, cette condition ne peut obtenir que des clés étrangères.

select tc.table_schema, tc.table_name, kc.column_name,tc.constraint_type
from 
    information_schema.table_constraints tc
    JOIN information_schema.key_column_usage kc 
        on kc.table_name = tc.table_name and kc.table_schema = tc.table_schema 
                and kc.constraint_name = tc.constraint_name
where 
--kc.position_in_unique_constraint is not null
order by tc.table_schema,
         tc.table_name,
         kc.position_in_unique_constraint;

J'essaie de faire quelque chose comme ça (les noms de table sont légèrement différents, je suis probablement sur une version différente de postgres). La requête s'exécute mais je n'obtiens aucun résultat. Est-il possible que je n'ai pas les bonnes autorisations-?
szeitlin
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.