Как получить имя primary key?

Павел С.
Дата: 29.10.2003 19:21:00
Господа, каким образом можно получить имя столбца который является primary key в определённой таблице?
Konrad
Дата: 30.10.2003 08:13:33
\d table
Павел С.
Дата: 30.10.2003 11:34:35
Это понятно, а из приложения через запрос?
Konrad
Дата: 30.10.2003 12:41:59
psql -E database

Ключ -E заставит postgres выводить все запросы на экран.
И далее:
database=#\d table

См. в текст запросов..
Павел С.
Дата: 30.10.2003 15:07:51
Про директиву -Е весьма интересное упоминание, спасибо.
Но по какому запросу показывается что аттрибут является ключём. По \d ни какого упоминания об этом нет...
Shweik
Дата: 30.10.2003 20:40:55
pg_catalog.pg_index.indisprimary.


А это выресзка из комманды \d! Внимательней надо
SELECT c2.relname,i.indisprimary
--i.indisunique,
--pg_catalog.pg_get_indexdef(i.indexrelid)
FROM pg_catalog.pg_class c, pg_catalog.pg_class c2, pg_catalog.pg_index i
WHERE c.oid = '6221100' AND c.oid = i.indrelid AND i.indexrelid = c2.oid
ORDER BY i.indisprimary DESC, i.indisunique DESC, c2.relname;
Павел С.
Дата: 31.10.2003 10:09:56
Господа, вполне понимаю ваше негодование и нервный тон... Но я недавно работаю с PostgresSQL и к сожалению не знаю всех нюансов. Если вам не будет сложно, объясните пожалуста подробней. Я не приложу ума, что мне даёт последний предложенный запрос? Как мне получить имя primary key для совершенно определённой таблицы? Какую пользу я могу извлечь из pg_catalog.pg_index.indisprimary?
Konrad
Дата: 31.10.2003 11:30:20
Как мне получить имя primary key для совершенно определённой таблицы?

Пример.
Имеем таблицу table, где есть первичный ключ table_pkey.

Получить имя primary key, нам поможет следующий запрос (подсмотренный, кстати, с помощью опции psql -E):
SELECT c2.relname

FROM pg_class c, pg_class c2, pg_index i
WHERE c.relname = 'table' AND c.oid = i.indrelid AND i.indexrelid = c2.oid
AND i.indisprimary AND i.indisunique ORDER BY c2.relname


В данном запросе имя искомой таблицы описано алиасом c, а имя первичного ключа - алиасом c2. Далее берется oid искомой таблицы (согласно условию c.relname) и находится идентичное вхождение для поля indexrelid (оно, в свою очередь, отражает oid таблицы-"хозяина" ключа):
c.oid = i.indrelid AND i.indexrelid = c2.oid

Далее в запросе, думаю, все достаточно очевидно.
Павел, обратите внимание на фрагмент i.indisprimary в этом запросе. Данной конструкцией мы проверям поле indisprimary с булевым типом данных в таблице pg_index на соответствие истине.
Konrad
Дата: 31.10.2003 12:07:25
каким образом можно получить имя столбца который является primary key в определённой таблице?

Если ваш основной вопрос в этом, то немного дополняем предыдущий запрос:

SELECT c2.relname, a.attname

FROM pg_class c, pg_class c2, pg_index i, pg_attribute a
WHERE c.relname = 'table' AND c.oid = i.indrelid AND i.indexrelid = c2.oid
AND i.indisprimary AND i.indisunique
AND a.attrelid=c2.oid
AND a.attnum>0;


Что добавилось? Имя поля, являющегося PK, из системной таблицы pg_attribute. Основное условие - оно должно принадлежать сущности table_pkey (a.attrelid=c2.oid), т.е. самому PK.
Павел С.
Дата: 03.11.2003 12:31:35
Конрад, спасибо за обстоятельное объяснение и терпение проявленное к моему непрофессионализму. Но так у меня ни чего и не получается... :-(

Вот всё по порядку:
1. Создаю таблицу:
CREATE TABLE radcheck (
id SERIAL PRIMARY KEY,
UserName VARCHAR(30) DEFAULT '' NOT NULL,
Attribute VARCHAR(30),
op VARCHAR(2) NOT NULL DEFAULT '==',
Value VARCHAR(40)
);

2. Выполняю запрос:
SELECT c2.relname, a.attname
FROM pg_class c, pg_class c2, pg_index i, pg_attribute a
WHERE c.relname = 'radchecks' AND c.oid = i.indrelid AND i.indexrelid = c2.oid
AND i.indisprimary AND i.indisunique
AND a.attrelid=c2.oid
AND a.attnum>0;

3. Получаю ответ:
relname | attname
---------+---------
(0 rows)

Где ошибка?