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


14

Чи є запит, який буде робити це?

Я знайшов кілька запитів, які можуть зробити це для однієї таблиці, але я не зміг її змінити, щоб я міг бачити:

tablename | column | type

1
Якщо я запитував це, я хотів би знати порядкове положення стовпця в ПК (деякі ПК мають більше 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;

Цей запит показує не лише первинні ключі, але й унікальні індекси
Michał Niklas

@ MichałNiklas це не так.
dezso

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є недійсним лише у використанні FK.
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частину, тому в ній перераховані всі обмеження.


2
Поки ваш запит працює, важливішою відмінністю є відсутність and kc.position_in_unique_constraint is not nullчастини. І вам настійно рекомендується використовувати ANSI JOIN (хоча багато хто вважає це справою смаку).
dezso

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 Ласкаво просимо на форум!
Vérace

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;

Я намагаюся зробити щось подібне (назви таблиць дещо відрізняються, я, мабуть, на іншій версії постгресів). Запит працює, але я не отримаю жодних результатів. Чи можливо, що я не маю правильних дозволів?
szeitlin
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.