Быстро и грязно
В Postgres 9.4+ используйте
SELECT to_regclass('foo');
Возвращает NULL, если идентификатор не найден в пути поиска.
В Postgres 9.3 и старше используйте приведение кregclass
:
SELECT 'foo'::regclass;
Это вызывает исключение , если объект не найден!
Если 'foo'
найден, oid
возвращается в его text
представлении. Это просто имя таблицы, дополненное схемой в соответствии с текущим путем поиска и, при необходимости, в двойных кавычках.
Если объект не найден, вы можете быть уверены, что он не существует нигде в пути поиска - или вообще не существует для имени, дополненного схемой ( schema.foo
).
Если он найден, есть два недостатка :
Поиск включает неявные схемы search_path , а именно pg_catalog
иpg_temp
. Но вы можете исключить временные и системные таблицы для ваших целей. (?)
Приведение к regclass
работе для всех объектов в системном каталоге pg_class
: индексы, представления, последовательности и т. Д. Не только таблицы. Вы, кажется, ищете обычный стол исключительно. Однако у вас, вероятно, будут проблемы и с другими объектами с таким же именем. Подробности:
Медленно и уверенно
Мы вернулись к вашему запросу, но не используем current_setting('search_path')
, который возвращает пустую настройку. Используйте выделенную функцию системной информации current_schemas()
. По документации:
current_schemas(boolean)
name[]
имена схем в пути поиска, необязательно включая неявные схемы
"$user"
в пути поиска решается хитро. Если никакой схемы с именем SESSION_USER
существует, схема не возвращается с самого начала. Кроме того, в зависимости от того, что именно вы хотите, вы можете дополнительно вывести неявные схемы ( pg_catalog
и, возможно, pg_temp
) - но я предполагаю, что вы не хотите использовать их для рассматриваемого случая, поэтому используйте:
DO
$do$
BEGIN
IF EXISTS (
SELECT -- list can be empty
FROM pg_catalog.pg_class c
JOIN pg_catalog.pg_namespace n ON n.oid = c.relnamespace
WHERE n.nspname = ANY(current_schemas(FALSE))
AND n.nspname NOT LIKE 'pg_%' -- exclude system schemas!
AND c.relname = 'foo'
AND c.relkind = 'r') -- you probably need this
THEN
RAISE 'This application depends on tables created by another application';
END IF;
END
$do$;
SQL Fiddle , демонстрирующая все, кроме последнегоDO
оператора.
У SQL Fiddle (JDBC) есть проблемы с DO
операторами, содержащими символы завершения.