Список первичных ключей для всех таблиц - Postgresql

14

Есть ли запрос, который сделает это?

Я нашел несколько запросов, которые могут сделать это для одной таблицы, но я не смог изменить ее, поэтому я вижу:

tablename | column | type
Корда
источник
1
Если бы я спрашивал об этом, я хотел бы знать порядковый номер столбца в PK (некоторые PK имеют более 1 столбца, и порядок может иметь значение).
ypercubeᵀᴹ

Ответы:

13

Что-то вроде этого:

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;
a_horse_with_no_name
источник
Этот запрос показывает не только первичные ключи, но и уникальные индексы
Михал Никлас
@ MichałNiklas это не так.
Дезсо
1
@DarielPratama: условие tc.constraint_type = 'PRIMARY KEY'будет показывать только первичные ключи. Однако каждый первичный ключ поддерживается уникальным индексом
a_horse_with_no_name
2
@a_horse_with_no_name Я верю, что это неправильно. position_in_unique_constraintуказывает позицию для клавиши FOREIGN, для первичных ключей она всегда равна нулю. Правильный столбец есть ordinal_position. Проверено в PG 9.4.
Greatvovan
1
@a_horse_with_no_name Я одобрил изменение, предложенное анонимным пользователем. Не уверен, что редактирование пройдет, другие отклонили. В любом случае, пожалуйста, проверьте предложение и комментарий выше greatvovan. Я думаю, что они правильные и ordinal_positionдолжны быть использованы. Не position_in_unique_constraintявляется нулевым только в использовании FKs.
ypercubeᵀᴹ
20

Это более точный ответ:

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;

Вы пропустили and kc.constraint_name = tc.constraint_nameчасть, поэтому в ней перечислены все ограничения.

mikipero
источник
2
Пока ваш запрос работает, более важным отличием является отсутствующая and kc.position_in_unique_constraint is not nullчасть. И вам настоятельно рекомендуется использовать ANSI JOIN (хотя многие считают это делом вкуса).
Дезсо
1

Пожалуйста, учтите это тоже. Это сгенерирует скрипт для изменения всех таблиц.

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;
Мартин
источник
Вопрос не в том, как изменить таблицы.
ypercubeᵀᴹ
1
Я второй, что @ ypercubeᵀᴹsays. Удалите этот ответ, но не отчаивайтесь - отправляйтесь в тур, посетите справочный центр и прочитайте блог «Помогите нам помочь». Что касается ответа на то, что не было задано, мы все это делали много раз :-). ps добро пожаловать на форум!
Верас
1

Я думаю, чтобы получить первичный ключ и внешний ключ должен сделать так. kc.position_in_unique_constraint не является нулевым, это условие может получить только внешние ключи.

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;
Юаньвэнь Ли
источник
Я пытаюсь сделать что-то вроде этого (имена таблиц немного отличаются, я, вероятно, на другой версии postgres). Запрос выполняется, но я не получаю никаких результатов. Возможно ли, что у меня нет необходимых разрешений?
szeitlin