PostgreSQL
 sql >> Baza danych >  >> RDS >> PostgreSQL

Jak sprawdzić, czy w danym schemacie istnieje tabela?

To zależy od tego, co chcesz dokładnie przetestować .

Schemat informacji?

Aby dowiedzieć się, „czy stół istnieje” (niezależnie od tego, kto pyta ), odpytywanie schematu informacji (information_schema.tables ) jest nieprawidłowe , ściśle mówiąc, ponieważ (według dokumentacji):

Wyświetlane są tylko te tabele i widoki, do których bieżący użytkownik ma dostęp (poprzez bycie właścicielem lub posiadanie uprawnień).

Zapytanie dostarczone przez @kong może zwrócić FALSE , ale tabela może nadal istnieć. Odpowiada na pytanie:

Jak sprawdzić, czy istnieje tabela (lub widok) i czy bieżący użytkownik ma do niej dostęp?

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

Schemat informacji jest przydatny głównie do zachowania mobilności w głównych wersjach i różnych RDBMS. Jednak implementacja jest powolna, ponieważ Postgres musi używać zaawansowanych widoków, aby zachować zgodność ze standardem (information_schema.tables jest dość prostym przykładem). Niektóre informacje (takie jak identyfikatory OID) giną w tłumaczeniu z katalogów systemowych - co właściwie nosić wszystkie informacje.

Katalogi systemowe

Twoje pytanie brzmiało:

Jak sprawdzić, czy tabela istnieje?

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

Użyj katalogów systemowych pg_class i pg_namespace bezpośrednio, co jest również znacznie szybsze. Jednak zgodnie z dokumentacją na pg_class :

Katalog pg_class kataloguje tabele i prawie wszystko, co ma kolumny lub jest w inny sposób podobne do tabeli. Obejmuje to indeksy (ale zobacz także pg_index ), sekwencje , wyświetlenia , widoki zmaterializowane , typy złożone i stoły TOSTY;

W przypadku tego konkretnego pytania możesz również użyć widoku systemowego pg_tables . Nieco prostsze i bardziej przenośne w głównych wersjach Postgresa (co nie jest problemem w przypadku tego podstawowego zapytania):

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

Identyfikatory muszą być unikalne wśród wszystkich obiekty wymienione powyżej. Jeśli chcesz zapytać:

Jak sprawdzić, czy nazwa tabeli lub podobnego obiektu w danym schemacie jest zajęta?

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'
   );
  • Powiązana odpowiedź na dba.SE omawiająca „Schemat informacji a katalogi systemowe”

Alternatywnie:rzutuj na regclass

SELECT 'schema_name.table_name'::regclass

To zgłasza wyjątek jeśli (opcjonalnie zakwalifikowana do schematu) tabela (lub inny obiekt o tej nazwie) nie istnieje.

Jeśli nie kwalifikujesz nazwy tabeli według schematu, rzutuj na regclass domyślnie search_path i zwraca OID dla pierwszej znalezionej tabeli — lub wyjątek, jeśli tabela nie znajduje się w żadnym z wymienionych schematów. Zauważ, że schematy systemowe pg_catalog i pg_temp (schemat dla tymczasowych obiektów bieżącej sesji) są automatycznie częścią search_path .

Możesz użyć tego i złapać możliwy wyjątek w funkcji. Przykład:

  • Sprawdź, czy sekwencja istnieje w Postgresie (plpgsql)

Zapytanie takie jak powyżej pozwala uniknąć możliwych wyjątków i dlatego jest nieco szybsze.

to_regclass(rel_name) w Postgresie 9.4+

Znacznie prostsze teraz:

SELECT to_regclass('schema_name.table_name');

Taka sama jak obsada, ale zwraca ...

... null zamiast zgłaszania błędu, jeśli nazwa nie zostanie znaleziona



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Powrót XFS na Linuksie

  2. Optymalizacja zapytań w PostgreSQL. WYJAŚNIJ podstawy – część 3

  3. Czy PostgreSQL obsługuje przezroczystą kompresję tabel (fragmentów)?

  4. array_agg dla typów tablic

  5. SQL, gdzie połączony zbiór musi zawierać wszystkie wartości, ale może zawierać więcej