sql >> Database >  >> RDS >> PostgreSQL

Hoe te controleren of een tabel in een bepaald schema bestaat

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 ook pg_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



  1. 7 manieren om uw Oracle-versie te controleren

  2. Breid EM Grid Control uit naar nieuwe nodes

  3. Meerdere databases gebruiken in Laravel

  4. 4 manieren om de definitie van een weergave te krijgen met Transact-SQL