PostgreSQL
 sql >> Base de données >  >> RDS >> PostgreSQL

Comment vérifier si une table existe dans un schéma donné

Cela dépend de ce que vous voulez tester exactement .

Schéma d'informations ?

Pour savoir "si la table existe" (peu importe qui demande ), en interrogeant le schéma d'information (information_schema.tables ) est incorrect , à proprement parler, parce que (selon la documentation) :

Seules les tables et les vues auxquelles l'utilisateur actuel a accès sont affichées (par le fait qu'il en est le propriétaire ou qu'il a des privilèges).

La requête fournie par @kong peut renvoyer FALSE , mais la table peut toujours exister. Il répond à la question :

Comment vérifier si une table (ou une vue) existe et si l'utilisateur actuel y a accès ?

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

Le schéma d'informations est principalement utile pour rester portable entre les principales versions et entre différents RDBMS. Mais l'implémentation est lente, car Postgres doit utiliser des vues sophistiquées pour se conformer au standard (information_schema.tables est un exemple assez simple). Et certaines informations (comme les OID) se perdent dans la traduction des catalogues système - ce qui en fait transporter toutes les informations.

Catalogues système

Votre question était :

Comment vérifier si une table existe ?

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

Utiliser les catalogues système pg_class et pg_namespace directement, ce qui est également beaucoup plus rapide. Cependant, selon la documentation sur pg_class :

Le catalogue pg_class catalogue les tables et la plupart de tout ce qui a des colonnes ou est similaire à une table. Cela inclut les index (mais voir aussi pg_index ), séquences , vues , vues matérialisées , types composites , et tableaux TOAST;

Pour cette question particulière, vous pouvez également utiliser la vue système pg_tables . Un peu plus simple et plus portable sur les principales versions de Postgres (ce qui n'est guère préoccupant pour cette requête de base) :

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

Les identifiants doivent être uniques parmi tous objets mentionnés ci-dessus. Si vous voulez demander :

Comment vérifier si un nom pour une table ou un objet similaire dans un schéma donné est pris ?

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'
   );
  • Réponse connexe sur dba.SE traitant de "Schéma d'information vs catalogues système"

Alternative :convertir en regclass

SELECT 'schema_name.table_name'::regclass

Cela lève une exception si la table (éventuellement qualifiée par le schéma) (ou tout autre objet portant ce nom) n'existe pas.

Si vous ne qualifiez pas de schéma le nom de la table, un cast en regclass par défaut le search_path et renvoie l'OID de la première table trouvée - ou une exception si la table n'est dans aucun des schémas listés. Notez que les schémas système pg_catalog et pg_temp (le schéma des objets temporaires de la session en cours) font automatiquement partie du search_path .

Vous pouvez l'utiliser et intercepter une exception possible dans une fonction. Exemple :

  • Vérifier si la séquence existe dans Postgres (plpgsql)

Une requête comme ci-dessus évite d'éventuelles exceptions et est donc légèrement plus rapide.

to_regclass(rel_name) dans Postgres 9.4+

Beaucoup plus simple maintenant :

SELECT to_regclass('schema_name.table_name');

Identique au casting, mais ça revient ...

... null plutôt que de lancer une erreur si le nom n'est pas trouvé