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