PostgreSQL
 sql >> база данни >  >> RDS >> PostgreSQL

Как да проверите дали таблица съществува в дадена схема

Зависи какво искате да теста точно .

Информационна схема?

За да разберете „дали таблицата съществува“ (без значение кой пита ), запитване на информационната схема (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 вместо да извежда грешка, ако името не бъде намерено



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Алтернативен изходен формат за psql

  2. Задаване на изчакване за свързване с PDO

  3. Разлика между език sql и език plpgsql във функциите на PostgreSQL

  4. Надстройте PostgreSQL JSON колоната до JSONB?

  5. Как да променя форматирането на връщаните ми стойности в тази функция?