Это зависит от того, что вы хотите , чтобы проверить точно .
Информационная схема?
Чтобы найти «существует ли таблица» ( независимо от того, кто спрашивает ), запрос информационной схемы ( information_schema.tables
) , строго говоря, некорректен , потому что ( согласно документации ):
Отображаются только те таблицы и представления, к которым у текущего пользователя есть доступ (будучи владельцем или обладающим некоторыми привилегиями).
Запрос, предоставленный @kong, может вернуться FALSE
, но таблица все еще может существовать. Это отвечает на вопрос:
Как проверить, существует ли таблица (или представление) и имеет ли текущий пользователь к ней доступ?
SELECT EXISTS (
SELECT FROM information_schema.tables
WHERE table_schema = 'schema_name'
AND table_name = 'table_name'
);
Информационная схема в основном полезна для переносимости между основными версиями и разными СУБД. Но реализация медленная, потому что Postgres должен использовать сложные представления, чтобы соответствовать стандарту ( information_schema.tables
это довольно простой пример). И некоторая информация (например, OID) теряется при переводе из системных каталогов - что на самом деле содержат всю информацию.
Системные каталоги
Ваш вопрос был:
Как проверить, существует ли таблица?
SELECT EXISTS (
SELECT FROM pg_catalog.pg_class c
JOIN pg_catalog.pg_namespace n ON n.oid = c.relnamespace
WHERE n.nspname = 'schema_name'
AND c.relname = 'table_name'
AND c.relkind = 'r' -- only tables
);
Используйте системные каталоги pg_class
и pg_namespace
напрямую, что также значительно быстрее. Тем не менее, согласно документации поpg_class
:
Каталог pg_class
каталогизирует таблицы и большинство всего остального, которое имеет столбцы или иным образом аналогично таблице. Это включает в себя индексы (но см. Также pg_index
), последовательности , представления , материализованные представления , составные типы и таблицы TOAST ;
Для этого конкретного вопроса вы также можете использовать системный видpg_tables
. Немного проще и более переносимо среди основных версий Postgres (что вряд ли относится к этому основному запросу):
SELECT EXISTS (
SELECT FROM pg_tables
WHERE schemaname = 'schema_name'
AND tablename = 'table_name'
);
Идентификаторы должны быть уникальными среди всех объектов, упомянутых выше. Если вы хотите спросить:
Как проверить, берется ли имя для таблицы или подобного объекта в данной схеме?
SELECT EXISTS (
SELECT FROM pg_catalog.pg_class c
JOIN pg_catalog.pg_namespace n ON n.oid = c.relnamespace
WHERE n.nspname = 'schema_name'
AND c.relname = 'table_name'
);
Альтернатива: приведение к regclass
SELECT 'schema_name.table_name'::regclass
Это вызывает исключение, если таблица (необязательно дополненная схемой) (или другой объект, занимающий это имя) не существует.
Если вы не квалифицируете схему имени таблицы, приведение к regclass
значениям по умолчанию search_path
и возвращает OID для первой найденной таблицы - или исключение, если таблица не входит ни в одну из перечисленных схем. Обратите внимание, что системные схемы pg_catalog
и pg_temp
(схема для временных объектов текущего сеанса) автоматически становятся частью search_path
.
Вы можете использовать это и поймать возможное исключение в функции. Пример:
Такой запрос позволяет избежать возможных исключений и поэтому работает немного быстрее.
Теперь намного проще:
SELECT to_regclass('schema_name.table_name');
То же, что и актерский состав, но он возвращается ...
... ноль, а не выдавать ошибку, если имя не найдено
[[ `psql dbname -tAc "SELECT EXISTS (SELECT 1 FROM information_schema.tables WHERE table_schema = 'ejabberd' AND table_name = 'users');"` = 't' ]]