sql >> Base de Datos >  >> RDS >> PostgreSQL

Cómo verificar si existe una tabla en un esquema dado

Depende de lo que quieras probar exactamente .

¿Esquema de información?

Para encontrar "si la tabla existe" (sin importar quién pregunte ), consultando el esquema de información (information_schema.tables ) es incorrecto , estrictamente 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 comprobar si existe una tabla (o vista) y si 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 en realidad 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
   );

Usa 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 catálogo pg_class cataloga tablas y casi todo lo demás que tiene columnas o es similar a una tabla. Esto incluye índices (pero vea también pg_index ), secuencias , vistas , vistas materializadas , tipos compuestos y tablas TOAST;

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 deben 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 sobre "Esquema de información frente a catálogos de sistemas"

Alternativa:transmitir a regclass

SELECT 'schema_name.table_name'::regclass

Esto provoca 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 el valor predeterminado es 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 de la search_path .

Puede usar eso y detectar una posible excepción en una función. Ejemplo:

  • Compruebe si la secuencia existe 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 PostgreSQL 9.4+

Mucho más simple ahora:

SELECT to_regclass('schema_name.table_name');

Igual que el elenco, pero vuelve...

... nulo en lugar de arrojar un error si no se encuentra el nombre