Получить значения по умолчанию для столбцов таблицы в Postgres? - PullRequest
21 голосов
/ 16 ноября 2011

Я ищу способ выполнить запрос, чтобы найти значения по умолчанию для столбцов таблицы в Postgres. Например, если я сделал таблицу со следующим запросом:

** Примечание редактора: я исправил определение таблицы, поскольку оно не влияет на вопрос.

CREATE TABLE mytable (
    integer int DEFAULT 2,
    text varchar(64) DEFAULT 'I am default',
    moretext varchar(64) DEFAULT 'I am also default',
    unimportant int 
);

Мне нужен запрос, который в каком-то формате сообщает мне, что по умолчанию для integer установлено значение 2, text - это «Я по умолчанию», а moretext - «Я также по умолчанию». Результат запроса может включать любое значение для любого другого столбца, который не имеет значения по умолчанию, то есть unimportant не имеет значения для моих целей и не имеет значения вообще.

Ответы [ 5 ]

41 голосов
/ 16 ноября 2011

Использовать информационную схему:

SELECT column_name, column_default
FROM information_schema.columns
WHERE (table_schema, table_name) = ('public', 'mytable')
ORDER BY ordinal_position;

 column_name │             column_default             
─────────────┼────────────────────────────────────────
 integer     │ 2
 text        │ 'I am default'::character varying
 moretext    │ 'I am also default'::character varying
 unimportant │ 
(4 rows)

Вплоть до именования схем это должно работать в любой системе баз данных SQL.

13 голосов
/ 16 ноября 2011

@ Запрос Зохайба почти, но не совсем правильный. Есть пара вопросов. Я скопировал его в свой ответ для дальнейшего использования. Не используйте это :

SELECT adsrc as default_value
 FROM pg_attrdef pad, pg_atttribute pat, pg_class pc
 WHERE pc.relname='your_table_name'
     AND pc.oid=pat.attrelid AND pat.attname='your_column_name'
     AND pat.attrelid=pad.adrelid AND pat.attnum=pad.adnum
  • Он скопирован из какого-то блога. То, что он упоминает, это хорошо. Но в таком случае источник должен быть добавлен. Люди, читающие этот блог, должны быть предупреждены.

  • Опечатка в pg_atttribute - исправлена ​​легко.

  • Не возвращает никаких строк, если для запрошенного столбца не задано значение по умолчанию. Лучше сделать это LEFT JOIN pg_attrdef ON .., чтобы вы всегда получали результирующую строку, если столбец существует. Это будет NULL, если нет значения по умолчанию, что на самом деле является правильным результатом, потому что NULL - это значение по умолчанию.

  • Если вы удалите attname из предложения WHERE, вы получите значения только для столбцов, которые действительно имеют значение по умолчанию. Не для других. И вам нужно добавить attname в список SELECT, или вы не будете знать, для какого столбца.

  • Запрос также возвращает значение по умолчанию для уже удаленного столбца, что является неверным . Подробнее о см. В руководстве .

  • Но самое главное: запрос может дать совершенно неправильный результат, так как он не учитывает имя схемы. В базе данных postgres может быть любое число table1.col1: в различных схемах. Если у нескольких есть значения по умолчанию, вы получите несколько значений. Если у столбца, который вы имеете в виду, нет значения по умолчанию, а у другого в другой схеме - вы будете обмануты и никогда его не узнаете.

Подводя итог:

Копирование / вставка из какого-либо блога без понимания пошло опасно неправильно!
Попробуйте вместо этого:

SELECT d.adsrc AS default_value
FROM   pg_catalog.pg_attribute a
LEFT   JOIN pg_catalog.pg_attrdef d ON (a.attrelid, a.attnum)
                                     = (d.adrelid,  d.adnum)
WHERE  NOT a.attisdropped   -- no dropped (dead) columns
AND    a.attnum > 0         -- no system columns
AND    a.attrelid = 'myschema.mytable'::regclass
AND    a.attname = 'mycolumn';

LEFT JOIN гарантирует, что вы получите результат, пока существует столбец. Если вы хотите исключить , сделайте вместо этого JOIN. Но будьте готовы к тому, чтобы время от времени не устраивать скандалов.

Имейте в виду, что специальное приведение ::regclass учитывает текущую настройку для search_path, поэтому даже если вы не включите схему в имя (что вам следует, безусловно!), Вы получите ожидаемый результат. Подробнее об этом читайте в руководстве .

Включая pg_class является избыточным, как только у нас будет OID таблицы. Пропустить и ускорить запрос.

1 голос
/ 26 октября 2016

Мне понравилось Ответ Эрвина , но возникли некоторые трудности:

  1. Иногда я получаю имена столбцов "........ pg.dropped.30 ......." и т. Д. Даже с квалификацией NOT a.attisdropped. Это было непоследовательным, мне пришлось просмотреть результаты и проверить имена столбцов.
  2. К возвращенному значению по умолчанию иногда прикреплялась приведенная форма, например, 'I am default'::character varying, который не работал, когда они вставляются во входные значения веб-формы. Я не мог придумать хороший способ удалить суффикс приведения, не сделав что-то вроде .replace(/::.*/, ''), что недостаточно надежно. Могу поспорить, что Эрвин может найти какой-то волшебный способ получить EVAL() возвращаемое значение и использовать столбец a.atttypid, чтобы получить правильный тип данных.

Итак, я вернулся к тому, что делал раньше:

BEGIN;
INSERT INTO mytable DEFAULT VALUES RETURNING *;
ROLLBACK;

Здесь следует отметить, что любые столбцы SERIAL будут увеличиваться. Вероятно, это не имеет значения, если оно уникально, если это просто индекс таблицы. В противном случае это нарушит условия сделки.

Другая вещь, на которую следует обратить внимание, - это любая TRIGGER AFTER/BEFORE INSERT, которая сработает, даже если INSERT откатится (хотя я думаю, что любые изменения, сделанные триггерной функцией, будут отменены.)

0 голосов
/ 16 ноября 2011
you can just type " \d table_name" command , then It will displays some information about the

таблица, например значение столбца по умолчанию.

- создать таблицу

skytf=> CREATE TABLE mytable (
skytf(>     a integer DEFAULT 2,
skytf(>     b varchar(64)  DEFAULT 'I am default',
skytf(>     c varchar(64)  DEFAULT 'I am also default'
skytf(> );
CREATE TABLE

- показать информацию таблицы

skytf=> \d mytable
                              Table "skytf.mytable"
 Column |         Type          |                   Modifiers                    
--------+-----------------------+------------------------------------------------
 a      | integer               | default 2
 b      | character varying(64) | default 'I am default'::character varying
 c      | character varying(64) | default 'I am also default'::character varying
0 голосов
/ 16 ноября 2011
 SELECT adsrc as default_value
 FROM pg_attrdef pad, pg_atttribute pat, pg_class pc
 WHERE pc.relname='your_table_name'
     AND pc.oid=pat.attrelid AND pat.attname='your_column_name'
     AND pat.attrelid=pad.adrelid AND pat.attnum=pad.adnum

Я нашел этот запрос для postgresql в одном из блогов.Вы можете попробовать это, чтобы проверить, работает ли это.Чтобы получить значения всех кумнов, вы можете попробовать удалить AND pat.attname='your_column_name' из предложения where.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...