sql >> Database teknologi >  >> RDS >> PostgreSQL

Sådan kontrolleres om en tabel findes i et givet skema

Det afhænger af, hvad du vil teste præcis .

Oplysningsskema?

For at finde "om bordet eksisterer" (uanset hvem der spørger ), forespørger informationsskemaet (information_schema.tables ) er forkert , strengt taget, fordi (pr. dokumentation):

Kun de tabeller og visninger vises, som den aktuelle bruger har adgang til (ved at være ejer eller have et privilegium).

Forespørgslen leveret af @kong kan returnere FALSE , men tabellen kan stadig eksistere. Det besvarer spørgsmålet:

Hvordan kontrollerer man, om en tabel (eller visning) eksisterer, og den aktuelle bruger har adgang til den?

SELECT EXISTS (
   SELECT FROM information_schema.tables 
   WHERE  table_schema = 'schema_name'
   AND    table_name   = 'table_name'
   );

Informationsskemaet er hovedsageligt nyttigt til at forblive bærbart på tværs af større versioner og på tværs af forskellige RDBMS. Men implementeringen er langsom, fordi Postgres skal bruge sofistikerede visninger for at overholde standarden (information_schema.tables er et ret simpelt eksempel). Og nogle oplysninger (som OID'er) går tabt i oversættelsen fra systemkatalogerne - hvilket faktisk bære alle oplysninger.

Systemkataloger

Dit spørgsmål var:

Hvordan kontrollerer man, om en tabel eksisterer?

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
   );

Brug systemkatalogerne pg_class og pg_namespace direkte, hvilket også er betydeligt hurtigere. Dog pr. dokumentation på pg_class :

Kataloget pg_class katalogiserer tabeller og det meste andet, der har kolonner eller på anden måde ligner en tabel. Dette inkluderer indekser (men se også pg_index ), sekvenser , visninger , materialiserede visninger , sammensatte typer , og TOAST-tabeller;

Til dette specifikke spørgsmål kan du også bruge systemvisningen pg_tables . Lidt enklere og mere bærbar på tværs af større Postgres-versioner (hvilket næppe er bekymrende for denne grundlæggende forespørgsel):

SELECT EXISTS (
   SELECT FROM pg_tables
   WHERE  schemaname = 'schema_name'
   AND    tablename  = 'table_name'
   );

Identifikatorer skal være unikke blandt alle genstande nævnt ovenfor. Hvis du vil spørge:

Hvordan kontrollerer man, om et navn til en tabel eller lignende objekt i et givet skema er taget?

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'
   );
  • Relateret svar på dba.SE om "Informationsskema vs. systemkataloger"

Alternativ:cast til regclass

SELECT 'schema_name.table_name'::regclass

Dette hæver en undtagelse hvis den (valgfrit skema-kvalificerede) tabel (eller et andet objekt, der optager det navn) ikke eksisterer.

Hvis du ikke skemakvalificerer tabelnavnet, en cast til regclass er standard til search_path og returnerer OID for den første fundne tabel - eller en undtagelse, hvis tabellen ikke er i nogen af ​​de anførte skemaer. Bemærk, at systemskemaerne pg_catalog og pg_temp (skemaet for midlertidige objekter i den aktuelle session) er automatisk en del af search_path .

Du kan bruge det og fange en mulig undtagelse i en funktion. Eksempel:

  • Tjek, om sekvensen findes i Postgres (plpgsql)

En forespørgsel som ovenfor undgår mulige undtagelser og er derfor lidt hurtigere.

to_regclass(rel_name) i Postgres 9.4+

Meget enklere nu:

SELECT to_regclass('schema_name.table_name');

Samme som rollebesætningen, men det returnerer ...

... null i stedet for at smide en fejl, hvis navnet ikke findes



  1. Hvordan man erklærer input-output-parametre i SQL Server Stored Procedure/-funktion?

  2. MariaDB ROW_COUNT() Forklaret

  3. Kald en sæt-returnerende funktion med et array-argument flere gange

  4. Opret bruger fra strengvariabler i en PL/SQL-blok