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