Depende do que você deseja testar exatamente .
Esquema de informações?
Para descobrir "se a tabela existe" (não importa quem está perguntando ), consultando o esquema de informações (
information_schema.tables
) está incorreto , estritamente falando, porque (por documentação):
São mostradas apenas as tabelas e visualizações às quais o usuário atual tem acesso (por ser o proprietário ou ter algum privilégio).
A consulta fornecida por @kong pode retornar
FALSE
, mas a tabela ainda pode existir. Ele responde a pergunta:Como verificar se uma tabela (ou visualização) existe e se o usuário atual tem acesso a ela?
SELECT EXISTS (
SELECT FROM information_schema.tables
WHERE table_schema = 'schema_name'
AND table_name = 'table_name'
);
O esquema de informações é útil principalmente para permanecer portátil nas principais versões e em diferentes RDBMS. Mas a implementação é lenta, porque o Postgres precisa usar visualizações sofisticadas para cumprir o padrão (
information_schema.tables
é um exemplo bastante simples). E algumas informações (como OIDs) se perdem na tradução dos catálogos do sistema - o que na verdade levar todas as informações. Catálogos do sistema
Sua pergunta foi:
Como verificar se existe uma tabela?
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
);
Use os catálogos do sistema
pg_class
e pg_namespace
diretamente, o que também é consideravelmente mais rápido. No entanto, de acordo com a documentação em pg_class
:
O catálogopg_class
cataloga tabelas e quase tudo que tem colunas ou é similar a uma tabela. Isso inclui índices (mas veja tambémpg_index
), sequências , visualizações , visualizações materializadas , tipos compostos e mesas TOAST;
Para esta pergunta em particular, você também pode usar a visualização do sistema
pg_tables
. Um pouco mais simples e mais portátil nas principais versões do Postgres (o que dificilmente é uma preocupação para esta consulta básica):SELECT EXISTS (
SELECT FROM pg_tables
WHERE schemaname = 'schema_name'
AND tablename = 'table_name'
);
Os identificadores devem ser únicos entre todos objetos mencionados acima. Se você quiser perguntar:
Como verificar se um nome para uma tabela ou objeto semelhante em um determinado esquema foi usado?
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'
);
- Resposta relacionada no dba.SE discutindo "Esquema de informações vs. catálogos do sistema"
Alternativa:transmitir para regclass
SELECT 'schema_name.table_name'::regclass
Isso gera uma exceção se a tabela (opcionalmente qualificada pelo esquema) (ou outro objeto ocupando esse nome) não existir.
Se você não qualificar o nome da tabela pelo esquema, uma conversão para
regclass
o padrão é o search_path
e retorna o OID da primeira tabela encontrada - ou uma exceção se a tabela não estiver em nenhum dos esquemas listados. Observe que os esquemas do sistema pg_catalog
e pg_temp
(o esquema para objetos temporários da sessão atual) são automaticamente parte do search_path
. Você pode usar isso e capturar uma possível exceção em uma função. Exemplo:
- Verifique se a sequência existe no Postgres (plpgsql)
Uma consulta como a acima evita possíveis exceções e, portanto, é um pouco mais rápida.
to_regclass(rel_name)
no Postgres 9.4+
Muito mais simples agora:
SELECT to_regclass('schema_name.table_name');
Igual ao elenco, mas ele retorna...
... null em vez de lançar um erro se o nome não for encontrado