テストする内容によって異なります正確に 。
情報スキーマ?
「テーブルが存在するかどうか」を見つけるため(誰が質問しても )、情報スキーマ(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