Rápido y sucio
En Postgres 9.4+ uso
SELECT to_regclass('foo');
Devuelve NULL si el identificador no se encuentra en la ruta de búsqueda.
En Postgres 9.3 o anterior, usa un yeso pararegclass
:
SELECT 'foo'::regclass;
¡Esto genera una excepción si no se encuentra el objeto!
Si 'foo'
se encuentra, oid
se devuelve en su text
representación. Ese es solo el nombre de la tabla, calificado por el esquema de acuerdo con la ruta de búsqueda actual y entre comillas dobles cuando sea necesario.
Si no se encuentra el objeto, puede estar seguro de que no existe en ninguna parte de la ruta de búsqueda, o que no existe para un nombre calificado con esquema ( schema.foo
).
Si se encuentra hay dos deficiencias :
La búsqueda incluye esquemas implícitos de search_path , a saber, pg_catalog
ypg_temp
. Pero es posible que desee excluir las tablas temporales y del sistema para su propósito. (?)
Un reparto regclass
para todos los objetos del catálogo del sistema pg_class
: índices, vistas, secuencias, etc. No solo tablas. Parece que estás buscando una mesa regular exclusivamente. Sin embargo, probablemente también tenga problemas con otros objetos del mismo nombre. Detalles:
Lento y seguro
Volvemos a su consulta, pero no use current_setting('search_path')
, lo que devuelve la configuración básica. Use la función de información del sistema dedicada current_schemas()
. Por documentación:
current_schemas(boolean)
name[]
nombres de esquemas en la ruta de búsqueda, opcionalmente incluidos esquemas implícitos
"$user"
en la ruta de búsqueda se resuelve de manera inteligente. Si no existe un esquema con el nombre de SESSION_USER
, el esquema no se devuelve para empezar. Además, dependiendo de lo que desee exactamente, también puede generar esquemas implícitos ( pg_catalog
y posiblemente pg_temp
), pero supongo que no los quiere para el caso en cuestión, así que 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 , que muestra todo excepto la últimaDO
declaración.
SQL Fiddle (JDBC) tiene problemas con las DO
declaraciones que contienen caracteres de terminación.