Dipende da cosa vuoi testare esattamente .
Schema di informazioni?
Per trovare "se il tavolo esiste" (non importa chi lo sta chiedendo ), interrogando lo schema delle informazioni (information_schema.tables
) è errato , in senso stretto, perché (per documentazione):
Vengono mostrate solo le tabelle e le viste a cui l'utente corrente ha accesso (in quanto proprietario o privilegio).
La query fornita da @kong può restituire FALSE
, ma la tabella può ancora esistere. Risponde alla domanda:
Come verificare se esiste una tabella (o vista) e l'utente corrente vi ha accesso?
SELECT EXISTS (
SELECT FROM information_schema.tables
WHERE table_schema = 'schema_name'
AND table_name = 'table_name'
);
Lo schema delle informazioni è utile principalmente per mantenere la portabilità tra le versioni principali e tra diversi RDBMS. Ma l'implementazione è lenta, perché Postgres deve utilizzare viste sofisticate per conformarsi allo standard (information_schema.tables
è un esempio piuttosto semplice). E alcune informazioni (come gli OID) vengono perse durante la traduzione dai cataloghi di sistema, il che in realtà trasportare tutte le informazioni.
Cataloghi di sistema
La tua domanda era:
Come verificare se esiste una tabella?
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 i cataloghi di sistema pg_class
e pg_namespace
direttamente, che è anche notevolmente più veloce. Tuttavia, secondo la documentazione su pg_class
:
Il catalogo pg_class
cataloga i tavoli e quasi tutto ciò che ha colonne o è comunque simile a un tavolo. Ciò include indici (ma vedi anche pg_index
), sequenze , viste , viste materializzate , tipi compositi e tabelle TOAST;
Per questa particolare domanda puoi anche usare la vista di sistema pg_tables
. Un po' più semplice e più portabile nelle principali versioni di Postgres (che non è certo un problema per questa query di base):
SELECT EXISTS (
SELECT FROM pg_tables
WHERE schemaname = 'schema_name'
AND tablename = 'table_name'
);
Gli identificatori devono essere univoci tra tutti oggetti di cui sopra. Se vuoi chiedere:
Come verificare se viene preso un nome per una tabella o un oggetto simile in un determinato schema?
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'
);
- Risposta correlata su dba.SE che discute di "Schema delle informazioni vs. cataloghi di sistema"
Alternativa:trasmettere a regclass
SELECT 'schema_name.table_name'::regclass
Questo solleva un'eccezione se la tabella (facoltativamente qualificata per lo schema) (o altro oggetto che occupa quel nome) non esiste.
Se non qualifichi lo schema del nome della tabella, un cast a regclass
il valore predefinito è search_path
e restituisce l'OID per la prima tabella trovata o un'eccezione se la tabella non è in nessuno degli schemi elencati. Si noti che gli schemi di sistema pg_catalog
e pg_temp
(lo schema per gli oggetti temporanei della sessione corrente) fanno automaticamente parte del search_path
.
Puoi usarlo e catturare una possibile eccezione in una funzione. Esempio:
- Verifica se la sequenza esiste in Postgres (plpgsql)
Una query come sopra evita possibili eccezioni ed è quindi leggermente più veloce.
to_regclass(rel_name)
in Postgres 9.4+
Molto più semplice ora:
SELECT to_regclass('schema_name.table_name');
Come il cast, ma ritorna...
... null anziché generare un errore se il nome non viene trovato