Veloce e sporco
In Postgres 9.4+ utilizzare
SELECT to_regclass('foo');
Restituisce NULL se l'identificatore non viene trovato nel percorso di ricerca.
In Postgres 9.3 o precedenti usa un cast perregclass
:
SELECT 'foo'::regclass;
Ciò solleva un'eccezione , se l'oggetto non viene trovato!
Se 'foo'
viene trovato, oid
viene restituito nella sua text
rappresentazione. Questo è solo il nome della tabella, qualificato dallo schema in base al percorso di ricerca corrente e tra virgolette doppie, se necessario.
Se l'oggetto non viene trovato, si può essere certi che non esiste da nessuna parte nel percorso di ricerca - o che non sia affatto per un nome qualificato da schema ( schema.foo
).
Se viene rilevato ci sono due carenze :
La ricerca include schemi impliciti del percorso di ricerca , vale a dire pg_catalog
epg_temp
. Ma potresti voler escludere tabelle temporanee e di sistema per i tuoi scopi. (?)
Un cast regclass
funziona per tutti gli oggetti nel catalogo di sistema pg_class
: indici, viste, sequenze ecc. Non solo tabelle. Sembra che tu stia cercando esclusivamente un tavolo normale. Tuttavia, probabilmente avrai problemi anche con altri oggetti con lo stesso nome. Dettagli:
Lento e sicuro
Siamo tornati alla tua query, ma non utilizziamo current_setting('search_path')
, che restituisce l'impostazione non elaborata. Utilizzare la funzione di informazioni di sistema dedicata current_schemas()
. Per documentazione:
current_schemas(boolean)
name[]
nomi di schemi nel percorso di ricerca, facoltativamente inclusi schemi impliciti
"$user"
nel percorso di ricerca viene risolto in modo intelligente. Se non esiste uno schema con il nome di SESSION_USER
, lo schema non viene restituito per cominciare. Inoltre, a seconda di cosa vuoi esattamente, puoi anche generare schemi impliciti ( pg_catalog
e possibilmente pg_temp
) - ma suppongo che tu non li voglia per il caso a portata di mano, quindi usa:
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 , dimostrando tutto tranne l'ultimaDO
dichiarazione.
SQL Fiddle (JDBC) ha problemi con le DO
istruzioni contenenti caratteri di terminazione.