Esta es la respuesta más válida que encomtrarás aportar, sin embargo estúdiala detenidamente y valora si se puede adaptar a tu proyecto.
Solución:
Depende de lo que quieras probar. exactamente.
esquema de información?
Para encontrar “si la tabla existe” (no importa quién pregunte), consultando el esquema de información (information_schema.tables
) es incorrectoestrictamente hablando, porque (por documentación):
Solo se muestran aquellas tablas y vistas a las que el usuario actual tiene acceso (por ser propietario o tener algún privilegio).
La consulta proporcionada por @kong puede devolver FALSE
, pero la tabla aún puede existir. Responde a la pregunta:
¿Cómo verificar si existe una tabla (o vista) y el usuario actual tiene acceso a ella?
SELECT EXISTS (
SELECT FROM information_schema.tables
WHERE table_schema = 'schema_name'
AND table_name = 'table_name'
);
El esquema de información es principalmente útil para mantener la portabilidad en las versiones principales y en diferentes RDBMS. Pero la implementación es lenta, porque Postgres tiene que usar vistas sofisticadas para cumplir con el estándar (information_schema.tables
es un ejemplo bastante simple). Y parte de la información (como los OID) se pierde en la traducción de los catálogos del sistema, que Realmente llevar toda la información.
Catálogos del sistema
Tu pregunta fue:
¿Cómo comprobar si existe una tabla?
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
);
Usar los catálogos del sistema pg_class
y pg_namespace
directamente, que también es considerablemente más rápido. Sin embargo, según la documentación en pg_class
:
el catalogo
pg_class
cataloga tablas y casi todo lo demás que tiene columnas o es similar a una tabla. Esto incluye índices (pero ver tambiénpg_index
), secuencias, puntos de vista, vistas materializadas, tipos compuestosy mesas TOSTADAS;
Para esta pregunta en particular, también puede usar la vista del sistema pg_tables
. Un poco más simple y más portátil en las principales versiones de Postgres (lo que no es motivo de preocupación para esta consulta básica):
SELECT EXISTS (
SELECT FROM pg_tables
WHERE schemaname = 'schema_name'
AND tablename = 'table_name'
);
Los identificadores tienen que ser únicos entre todos objetos antes mencionados. Si quieres preguntar:
¿Cómo verificar si se toma un nombre para una tabla u objeto similar en un esquema dado?
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'
);
- Respuesta relacionada en dba.SE discutiendo “Esquema de información vs. catálogos del sistema”
Alternativa: lanzar a regclass
SELECT 'schema_name.table_name'::regclass
Este plantea una excepción si la tabla (opcionalmente calificada por el esquema) (u otro objeto que ocupe ese nombre) no existe.
Si no califica el esquema del nombre de la tabla, una conversión a regclass
por defecto a la search_path
y devuelve el OID de la primera tabla encontrada, o una excepción si la tabla no se encuentra en ninguno de los esquemas enumerados. Tenga en cuenta que los esquemas del sistema pg_catalog
y pg_temp
(el esquema para los objetos temporales de la sesión actual) son automáticamente parte del search_path
.
Puede usar eso y detectar una posible excepción en una función. Ejemplo:
- Compruebe si existe una secuencia en Postgres (plpgsql)
Una consulta como la anterior evita posibles excepciones y, por lo tanto, es un poco más rápida.
to_regclass(rel_name)
en Postgres 9.4+
Mucho más simple ahora:
SELECT to_regclass('schema_name.table_name');
Igual que el elenco, pero vuelve …
… null en lugar de arrojar un error si no se encuentra el nombre
Tal vez use information_schema:
SELECT EXISTS(
SELECT *
FROM information_schema.tables
WHERE
table_schema = 'company3' AND
table_name = 'tableincompany3schema'
);
No se te olvide dar recomendación a esta división si te fue de ayuda.