Зависи какво искате да теста точно .
Информационна схема?
За да разберете „дали таблицата съществува“ (без значение кой пита ), запитване на информационната схема (information_schema.tables
) енеправилно , строго погледнато, защото (по документация):
Показват се само онези таблици и изгледи, до които текущият потребител има достъп (като е собственик или има някакви привилегии).
Заявката, предоставена от @kong, може да върне FALSE
, но таблицата все още може да съществува. Отговаря на въпроса:
Как да проверя дали таблица (или изглед) съществува и текущият потребител има достъп до нея?
SELECT EXISTS (
SELECT FROM information_schema.tables
WHERE table_schema = 'schema_name'
AND table_name = 'table_name'
);
Информационната схема е полезна главно, за да остане преносима в основните версии и в различни RDBMS. Но внедряването е бавно, тъй като Postgres трябва да използва сложни изгледи, за да отговаря на стандарта (information_schema.tables
е доста прост пример). И част от информацията (като OID) се губи при превод от системните каталози - което всъщност носи цялата информация.
Системни каталози
Въпросът ви беше:
Как да проверя дали съществува таблица?
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
);
Използвайте системните каталози pg_class
и pg_namespace
директно, което също е значително по-бързо. Въпреки това, според документация за pg_class
:
Каталогът
pg_class
каталогизира таблици и почти всичко останало, което има колони или по друг начин е подобно на таблица. Това включва индекси (но вижте същоpg_index
),последователности , прегледи ,материализирани изгледи ,композитни типове , и TOAST таблици;
За този конкретен въпрос можете също да използвате системния изглед pg_tables
. Малко по-просто и по-преносимо в основните версии на Postgres (което едва ли е от значение за тази основна заявка):
SELECT EXISTS (
SELECT FROM pg_tables
WHERE schemaname = 'schema_name'
AND tablename = 'table_name'
);
Идентификаторите трябва да са уникални сред всички обекти, споменати по-горе. Ако искате да попитате:
Как да проверя дали е взето име за таблица или подобен обект в дадена схема?
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'
);
- Свързан отговор на dba.SE, обсъждащ „Информационна схема срещу системни каталози“
Алтернатива:прехвърляне към regclass
SELECT 'schema_name.table_name'::regclass
Това поражда изключение ако таблицата (по избор с квалифицирана схема) (или друг обект, заемащ това име) не съществува.
Ако не квалифицирате по схема името на таблицата, прехвърляне към regclass
по подразбиране е search_path
и връща OID за първата намерена таблица - или изключение, ако таблицата не е в нито една от изброените схеми. Имайте предвид, че системните схеми pg_catalog
и pg_temp
(схемата за временни обекти на текущата сесия) автоматично са част от search_path
.
Можете да използвате това и да хванете възможно изключение във функция. Пример:
- Проверете дали съществува последователност в Postgres (plpgsql)
Заявка като по-горе избягва възможни изключения и следователно е малко по-бърза.
to_regclass(rel_name)
в Postgres 9.4+
Много по-просто сега:
SELECT to_regclass('schema_name.table_name');
Същото като актьорския състав, но връща се ...
... null вместо да извежда грешка, ако името не бъде намерено