正確に何をテストしたいかによります。
情報スキーマ?
(テーブルが存在するかどうか)(誰が質問しているかに関係なく)を見つけるために、情報スキーマ(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'
);
SELECT 'schema_name.table_name'::regclass
これは、例外を発生させ(スキーマ修飾)テーブル(またはその名前を占める他のオブジェクト)が存在しない場合。
テーブル名をスキーマ修飾しない場合、regclass
デフォルトのへのキャストによりsearch_path
、最初に見つかったテーブルのOIDが返されます。または、テーブルがリストされているスキーマのいずれにもない場合は例外が返されます。システムスキーマpg_catalog
およびpg_temp
(現在のセッションの一時オブジェクトのスキーマ)は自動的にの一部になることに注意してくださいsearch_path
。
これを使用して、関数で起こり得る例外をキャッチできます。例:
上記のようなクエリは、起こり得る例外を回避するため、わずかに高速です。
はるかに簡単になりました:
SELECT to_regclass('schema_name.table_name');
キャストと同じですが、戻ります...
...名前が見つからない場合にエラーをスローするのではなくnull
[[ `psql dbname -tAc "SELECT EXISTS (SELECT 1 FROM information_schema.tables WHERE table_schema = 'ejabberd' AND table_name = 'users');"` = 't' ]]