Het hangt af van wat u exact wilt testen .
Informatieschema?
Om te vinden "of de tafel bestaat" (ongeacht wie het vraagt ), het opvragen van het informatieschema (information_schema.tables
) is onjuist , strikt genomen, omdat (per documentatie):
Alleen die tabellen en weergaven worden getoond waartoe de huidige gebruiker toegang heeft (door de eigenaar te zijn of een bepaald privilege te hebben).
De zoekopdracht van @kong kan FALSE
return retourneren , maar de tabel kan nog steeds bestaan. Het beantwoordt de vraag:
Hoe controleer ik of een tabel (of weergave) bestaat en of de huidige gebruiker er toegang toe heeft?
SELECT EXISTS (
SELECT FROM information_schema.tables
WHERE table_schema = 'schema_name'
AND table_name = 'table_name'
);
Het informatieschema is vooral handig om overdraagbaar te blijven in de belangrijkste versies en in verschillende RDBMS. Maar de implementatie is traag, omdat Postgres geavanceerde views moet gebruiken om te voldoen aan de standaard (information_schema.tables
is een vrij eenvoudig voorbeeld). En sommige informatie (zoals OID's) gaat verloren in de vertaling van de systeemcatalogi - die eigenlijk dragen alle informatie.
Systeemcatalogi
Uw vraag was:
Hoe controleer je of een tafel bestaat?
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
);
Gebruik de systeemcatalogi pg_class
en pg_namespace
direct, wat ook nog eens aanzienlijk sneller is. Echter, volgens documentatie op pg_class
:
De catalogus
pg_class
catalogiseert tabellen en bijna al het andere dat kolommen heeft of op een andere manier lijkt op een tabel. Dit omvat indexen (maar zie ookpg_index
), reeksen , weergaven , gerealiseerde weergaven , composiettypen , en TOAST-tabellen;
Voor deze specifieke vraag kunt u ook de systeemweergave pg_tables
. gebruiken . Een beetje eenvoudiger en meer overdraagbaar in de belangrijkste Postgres-versies (wat nauwelijks van belang is voor deze basisvraag):
SELECT EXISTS (
SELECT FROM pg_tables
WHERE schemaname = 'schema_name'
AND tablename = 'table_name'
);
Identifiers moeten uniek zijn onder alle bovengenoemde objecten. Als je wilt vragen:
Hoe controleer je of een naam voor een tabel of soortgelijk object in een bepaald schema wordt gebruikt?
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'
);
- Gerelateerd antwoord op dba.SE over "Informatieschema versus systeemcatalogi"
Alternatief:casten naar regclass
SELECT 'schema_name.table_name'::regclass
Dit veroorzaakt een uitzondering als de (optioneel schema-gekwalificeerde) tabel (of ander object met die naam) niet bestaat.
Als u de tabelnaam niet schema-kwalificeert, een cast naar regclass
standaard ingesteld op het search_path
en retourneert de OID voor de eerste gevonden tabel - of een uitzondering als de tabel zich in geen van de vermelde schema's bevindt. Merk op dat de systeemschema's pg_catalog
en pg_temp
(het schema voor tijdelijke objecten van de huidige sessie) maken automatisch deel uit van het search_path
.
U kunt dat gebruiken en een mogelijke uitzondering in een functie opvangen. Voorbeeld:
- Controleer of een reeks bestaat in Postgres (plpgsql)
Een zoekopdracht zoals hierboven vermijdt mogelijke uitzonderingen en is daarom iets sneller.
to_regclass(rel_name)
in Postgres 9.4+
Veel eenvoudiger nu:
SELECT to_regclass('schema_name.table_name');
Hetzelfde als de cast, maar het keert terug ...
... null in plaats van een foutmelding te geven als de naam niet wordt gevonden