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