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) Postgres9.4以降

    今でははるかに簡単です:

    SELECT to_regclass('schema_name.table_name');
    

    キャストと同じですが、しかし 戻ります...

    ...名前が見つからない場合にエラーをスローするのではなくnull



    1. SQL-複数の類似クエリを組み合わせる

    2. ハッシュ何?ハッシュインデックスを理解する

    3. LinuxサーバーでMySQLテーブル名を大文字と小文字を区別しないように変更するにはどうすればよいですか?

    4. PostgreSQL:PostgreSQLですべてのテーブルのOWNERを同時に変更します