Rapido e sujo
No Postgres 9.4 ou superior, use
SELECT to_regclass('foo');
Retorna NULL se o identificador não for encontrado no caminho de pesquisa.
No Postgres 9.3 ou anterior, use um elenco pararegclass
:
SELECT 'foo'::regclass;
Isso gera uma exceção , se o objeto não for encontrado!
Se 'foo'
for encontrado, o oid
é retornado em sua text
representação. Esse é apenas o nome da tabela, qualificado pelo esquema de acordo com o caminho de pesquisa atual e aspas duplas, quando necessário.
Se o objeto não for encontrado, você pode ter certeza de que ele não existe em nenhum lugar no caminho de pesquisa - ou não existe um nome qualificado para o esquema ( schema.foo
).
Se for encontrado, existem duas deficiências :
A pesquisa inclui esquemas implícitos do search_path , ou seja, pg_catalog
epg_temp
. Mas você pode excluir tabelas temporárias e do sistema para seu propósito. (?)
Uma conversão regclass
para todos os objetos do catálogo do sistema pg_class
: índices, visualizações, sequências etc. Não apenas tabelas. Você parece estar procurando uma mesa regular exclusivamente. No entanto, você provavelmente também terá problemas com outros objetos com o mesmo nome. Detalhes:
Lento e seguro
Voltamos à sua consulta, mas não a usamos current_setting('search_path')
, que retorna a configuração vazia. Use a função de informações do sistema dedicada current_schemas()
. Por documentação:
current_schemas(boolean)
name[]
nomes de esquemas no caminho de pesquisa, incluindo opcionalmente esquemas implícitos
"$user"
no caminho de pesquisa é resolvido de forma inteligente. Se não existir um esquema com o nome de SESSION_USER
, o esquema não será retornado para começar. Além disso, dependendo do que você deseja exatamente, você pode extrair esquemas implícitos ( pg_catalog
e possivelmente pg_temp
) - mas presumo que você não os queira para o caso em questão, use:
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 , demonstrando tudo, exceto a últimaDO
instrução.
O SQL Fiddle (JDBC) tem problemas com DO
instruções que contêm caracteres de finalização.