Как я могу проверить, существует ли столбец в таблице, используя оператор SQL

Есть ли в PostgreSQL простая альтернатива этому оператору, созданному в Oracle?

select table_name from user_tab_columns
where table_name = myTable and column_name = myColumn;

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

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


person CSharpened    schedule 03.04.2012    source источник


Ответы (6)


Попробуй это :

SELECT column_name 
FROM information_schema.columns 
WHERE table_name='your_table' and column_name='your_column';
person Ramandeep Singh    schedule 03.04.2012
comment
Спасибо. Принято как ответ, поскольку это прямая альтернатива тому, что я делал в Oracle. - person CSharpened; 03.04.2012
comment
@CSharpened, какой запрос для Oracle? - person Evgeny; 18.04.2013
comment
Это чрезвычайно хрупкий ответ - например. если таблица с именем your_table появляется в schema, которая находится выше в search_path. Моя база данных PostGIS имеет месячную схему, каждая с одинаковыми именами таблиц; используя этот ответ, vicmap201208.address будет найден перед vicmap201910.address, потому что vicmap201208 появляется перед vicmap201910 на search_path (по уважительным причинам, которые я не хотел бы менять, просто чтобы заставить работать плохой ответ). [Как бывает, имена столбцов одинаковы для разных схем: дело не в этом] - person GT.; 03.12.2019

Принятый ответ правильный, но отсутствует схема и более приятный вывод (True/False):

SELECT EXISTS (SELECT 1 
FROM information_schema.columns 
WHERE table_schema='my_schema' AND table_name='my_table' AND column_name='my_column');
person juan Isaza    schedule 29.12.2015
comment
Также учитывается схема - person Shane Gannon; 18.09.2018
comment
Или просто SELECT true as exists FROM information_schema.columns WHERE ...; - person yoyo; 17.04.2021

Это проще (и безопасно для SQLi) с типами идентификаторов объектов PostgreSQL:

SELECT TRUE
FROM   pg_attribute 
WHERE  attrelid = 'myTable'::regclass  -- cast to a registered class (table)
AND    attname = 'myColumn'
AND    NOT attisdropped  -- exclude dropped (dead) columns
-- AND attnum > 0        -- exclude system columns (you may or may not want this)

Прочтите о значении столбцов в руководстве.

Если вы строите динамический SQL и имя вашего столбца указано в качестве параметра, вы можете использовать quote_ident(), чтобы избежать внедрения SQL:

...
AND    attname = quote_ident('myColumn');

Работает и для таблиц за пределами search_path:

...
WHERE  attrelid = 'mySchema.myTable'::regclass
...
person Erwin Brandstetter    schedule 03.04.2012

SELECT attname 
FROM pg_attribute 
WHERE attrelid = (SELECT oid FROM pg_class WHERE relname = 'YOURTABLENAME') 
AND attname = 'YOURCOLUMNNAME';

Конечно, замените YOURTABLENAME и YOURCOLUMNNAME правильными значениями. Если возвращается строка, столбец с таким именем существует, в противном случае — нет.

person aleroot    schedule 03.04.2012
comment
Спасибо за ответ. Хотя ваш пример работает нормально, я решил принять ответ Ramandeeps из-за его простоты и того факта, что он кажется более прямой альтернативой моей проблеме. - person CSharpened; 03.04.2012

В отличие от Oracle, PostgreSQL поддерживает стандартные представления ANSI INFORMATION_SCHEMA.

Соответствующее стандартное представление для user_tab_columns Oracle: information_schema.columns

http://www.postgresql.org/docs/current/static/infoschema-columns.html

person a_horse_with_no_name    schedule 03.04.2012

Вот аналогичный вариант ответа Эрвина Брандштеттера. Здесь мы также проверяем схему на случай, если у нас есть похожие таблицы в другой схеме.

SELECT TRUE FROM pg_attribute 
WHERE attrelid = (
    SELECT c.oid
    FROM pg_class c
    JOIN pg_namespace n ON n.oid = c.relnamespace
    WHERE 
        n.nspname = CURRENT_SCHEMA() 
        AND c.relname = 'YOURTABLENAME'
    )
AND attname = 'YOURCOLUMNNAME'
AND NOT attisdropped
AND attnum > 0
person user2434435    schedule 10.10.2016