sql >> Databáze >  >> RDS >> PostgreSQL

Jak zkontrolovat, zda tabulka v daném schématu existuje

Záleží na tom, co chcete přesně testovat .

Informační schéma?

Chcete-li zjistit „zda tabulka existuje“ (bez ohledu na to, kdo se ptá ), dotazování na informační schéma (information_schema.tables ) je nesprávný , přísně vzato, protože (podle dokumentace):

Jsou zobrazeny pouze ty tabulky a pohledy, ke kterým má aktuální uživatel přístup (jako vlastník nebo nějaké oprávnění).

Dotaz poskytnutý @kong může vrátit FALSE , ale tabulka může stále existovat. Odpovídá na otázku:

Jak zkontrolovat, zda tabulka (nebo zobrazení) existuje a aktuální uživatel k ní má přístup?

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

Informační schéma je užitečné hlavně proto, aby zůstalo přenosné mezi hlavními verzemi a mezi různými RDBMS. Implementace je ale pomalá, protože Postgres musí používat sofistikované pohledy, aby vyhověl standardu (information_schema.tables je poměrně jednoduchý příklad). A některé informace (jako OID) se ztratí při překladu ze systémových katalogů – což ve skutečnosti nést všechny informace.

Systémové katalogy

Vaše otázka byla:

Jak zkontrolovat, zda tabulka existuje?

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

Použijte systémové katalogy pg_class a pg_namespace přímo, což je také podstatně rychlejší. Nicméně podle dokumentace na pg_class :

Katalog pg_class katalogizuje tabulky a většinu všeho ostatního, co má sloupce nebo je jinak podobné tabulce. To zahrnuje indexy (ale viz také pg_index ), sekvence , zobrazení , materializované pohledy , kompozitní typy a stoly TOAST;

Pro tuto konkrétní otázku můžete také použít systémové zobrazení pg_tables . O něco jednodušší a přenosnější mezi hlavními verzemi Postgresu (což se u tohoto základního dotazu sotva týká):

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

Identifikátory musí být jedinečné mezi všemi výše uvedené objekty. Pokud se chcete zeptat:

Jak zkontrolovat, zda je použit název tabulky nebo podobného objektu v daném schématu?

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'
   );
  • Související odpověď na dba.SE o „Informační schéma vs. systémové katalogy“

Alternativa:přenést do regclass

SELECT 'schema_name.table_name'::regclass

To vyvolá výjimku pokud tabulka (volitelně kvalifikovaná pro schéma) (nebo jiný objekt zabírající toto jméno) neexistuje.

Pokud název tabulky nekvalifikujete podle schématu, přetypování na regclass výchozí je search_path a vrátí OID pro první nalezenou tabulku - nebo výjimku, pokud tabulka není v žádném z uvedených schémat. Všimněte si, že systémová schémata pg_catalog a pg_temp (schéma pro dočasné objekty aktuální relace) jsou automaticky součástí search_path .

Můžete to použít a zachytit možnou výjimku ve funkci. Příklad:

  • Zkontrolujte, zda existuje sekvence v Postgres (plpgsql)

Výše uvedený dotaz se vyhýbá možným výjimkám a je proto o něco rychlejší.

to_regclass(rel_name) v Postgres 9.4+

Nyní mnohem jednodušší:

SELECT to_regclass('schema_name.table_name');

Stejné jako obsazení, ale vrátí ...

... null namísto vyvolání chyby, pokud není název nalezen



  1. Zobrazte výsledky dotazů SQLite pomocí vertikálního výstupu

  2. Spojte 3 tabulky v SQL

  3. Jak zálohovat databáze MySQL pomocí AutoMySQLBackup

  4. Po upgradu PHP nemohu používat funkce mysql_*