PostgreSQL
 sql >> Datenbank >  >> RDS >> PostgreSQL

So überprüfen Sie, ob eine Tabelle in einem bestimmten Schema vorhanden ist

Es hängt davon ab, was Sie genau testen möchten .

Informationsschema?

Um herauszufinden, "ob die Tabelle existiert" (egal wer fragt ), Abfrage des Informationsschemas (information_schema.tables ) ist falsch , genau genommen, weil (laut Dokumentation):

Es werden nur die Tabellen und Ansichten angezeigt, auf die der aktuelle Benutzer Zugriff hat (indem er der Besitzer ist oder einige Privilegien hat).

Die von @kong bereitgestellte Abfrage kann FALSE zurückgeben , aber die Tabelle kann noch vorhanden sein. Es beantwortet die Frage:

Wie überprüfe ich, ob eine Tabelle (oder Ansicht) existiert und der aktuelle Benutzer Zugriff darauf hat?

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

Das Informationsschema ist hauptsächlich nützlich, um zwischen Hauptversionen und verschiedenen RDBMS portabel zu bleiben. Die Implementierung ist jedoch langsam, da Postgres ausgeklügelte Ansichten verwenden muss, um dem Standard zu entsprechen (information_schema.tables ist ein ziemlich einfaches Beispiel). Und einige Informationen (wie OIDs) gehen bei der Übersetzung aus den Systemkatalogen verloren - was eigentlich tragen alle Informationen.

Systemkataloge

Ihre Frage war:

Wie überprüfe ich, ob eine Tabelle existiert?

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

Verwenden Sie die Systemkataloge pg_class und pg_namespace direkt, was auch wesentlich schneller ist. Allerdings laut Dokumentation zu pg_class :

Der Katalog pg_class katalogisiert Tabellen und fast alles andere, das Spalten hat oder einer Tabelle auf andere Weise ähnlich ist. Dazu gehören Indizes (siehe aber auch pg_index ), Sequenzen , Aufrufe , materialisierte Aufrufe , zusammengesetzte Typen und TOAST-Tabellen;

Für diese spezielle Frage können Sie auch die Systemansicht pg_tables verwenden . Ein bisschen einfacher und über größere Postgres-Versionen portierbarer (was für diese grundlegende Abfrage kaum von Belang ist):

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

Bezeichner müssen unter allen eindeutig sein oben genannten Objekte. Wenn Sie fragen möchten:

Wie überprüfe ich, ob ein Name für eine Tabelle oder ein ähnliches Objekt in einem bestimmten Schema verwendet wird?

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'
   );
  • Verwandte Antwort auf dba.SE zum Thema "Informationsschema vs. Systemkataloge"

Alternative:in regclass umwandeln

SELECT 'schema_name.table_name'::regclass

Dies löst eine Ausnahme aus wenn die (optional schemaqualifizierte) Tabelle (oder ein anderes Objekt mit diesem Namen) nicht existiert.

Wenn Sie den Tabellennamen nicht schemaqualifizieren, erfolgt eine Umwandlung in regclass ist standardmäßig search_path und gibt die OID für die erste gefundene Tabelle zurück - oder eine Ausnahme, wenn sich die Tabelle in keinem der aufgelisteten Schemas befindet. Beachten Sie, dass die Systemschemata pg_catalog und pg_temp (das Schema für temporäre Objekte der aktuellen Sitzung) sind automatisch Teil des search_path .

Sie können das verwenden und eine mögliche Ausnahme in einer Funktion abfangen. Beispiel:

  • Überprüfen Sie, ob die Sequenz in Postgres (plpgsql) existiert

Eine Abfrage wie oben vermeidet mögliche Ausnahmen und ist daher etwas schneller.

to_regclass(rel_name) in Postgres 9.4+

Jetzt viel einfacher:

SELECT to_regclass('schema_name.table_name');

Dasselbe wie die Besetzung, aber es gibt ...

zurück

... null, anstatt einen Fehler zu werfen, wenn der Name nicht gefunden wird