[解決済み] 指定されたスキーマにテーブルが存在するかどうかを確認する方法
質問
Postgres 8.4 以降のデータベースでは、共通テーブルを
public
スキーマに、会社独自のテーブルを
company
スキーマを使用します。
company
スキーマ名は常に
'company'
で終わり、会社番号で終わります。
というようなスキーマがあるかもしれませんね。
public
company1
company2
company3
...
companynn
アプリケーションは常に1社で動作します。
は
search_path
は、odbcやnpgsqlの接続文字列で適宜指定してください。
search_path='company3,public'
指定されたテーブルが、指定されたディレクトリに存在するかどうかをどのように確認しますか?
companyn
スキーマは?
などです。
select isSpecific('company3','tablenotincompany3schema')
を返さなければなりません。
false
そして
select isSpecific('company3','tableincompany3schema')
を返さなければなりません。
true
.
いずれにせよ、この関数がチェックすべきなのは
companyn
スキーマが渡され、他のスキーマは渡されない。
あるテーブルが
public
と渡されたスキーマを比較した場合、この関数は
true
.
Postgres 8.4 以降で動作するはずです。
解決方法は?
何をテストしたいかによります まさに .
情報スキーマ?
テーブルが存在するかどうかを調べるには、(
誰が聞いても
)、情報スキーマを問い合わせる(
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'
);
代替:キャスト
regclass
SELECT 'schema_name.table_name'::regclass
これは は例外を発生させます。 (オプションでスキーマ修飾された) テーブル (あるいはその名前を占める他のオブジェクト) が存在しない場合。
テーブル名をスキーマ修飾していない場合、テーブル名へのキャストを
regclass
はデフォルトで
search_path
を実行し、最初に見つかったテーブルのOIDを返します。テーブルがリストされたスキーマのいずれにも含まれていない場合は例外が発生します。なお、システムスキーマ
pg_catalog
と
pg_temp
(現在のセッションの一時的なオブジェクトのスキーマ) は、自動的に
search_path
.
それを使って、関数の中で起こりうる例外をキャッチすることができます。例
上記のようなクエリは、起こりうる例外を回避することができるため、若干高速になります。
to_regclass(rel_name)
Postgres 9.4+の場合
よりシンプルになりました。
SELECT to_regclass('schema_name.table_name');
キャストと同じです。 しかし を返します。
... 名前が見つからない場合にエラーを投げるのではなく、NULLを投げる
関連
-
[解決済み] SQL ServerでSELECTからUPDATEする方法とは?
-
[解決済み] PHPでSQLインジェクションを防ぐにはどうしたらいいですか?
-
[解決済み] SQLテーブルで重複する値を検索する
-
[解決済み] PostgreSQLの "DESCRIBE TABLE"
-
[解決済み] UNIONとUNION ALLの違いは何ですか?
-
[解決済み] INNER JOIN ON vs WHERE句
-
[解決済み] MySQLテーブルへの挿入または存在する場合の更新
-
[解決済み] SQL Server 2008を使用してIDENTITY_INSERTをオン/オフする方法は?
-
[解決済み] Selectステートメントで特定のフィールドの重複を検索する
-
[解決済み】SQL Serverで既存のテーブルにデフォルト値を持つカラムを追加する
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み] 1つのPostgreSQLクエリで複数のWITHステートメントを使用するには?
-
[解決済み] データベースのインデックス作成はどのように行われるのですか?[クローズド]
-
[解決済み] テーブルネーミングのジレンマ:単数形と複数形の名前【非公開
-
[解決済み] INNER JOIN ON vs WHERE句
-
[解決済み] ある列の最大値を持つ行を取得する
-
[解決済み] フラットテーブルをツリーにパースする最も効率的/エレガントな方法は何ですか?
-
[解決済み] Selectステートメントで特定のフィールドの重複を検索する
-
[解決済み] PostgreSQLでカラムが存在しない場合、どのように追加しますか?
-
[解決済み] Postgresデータベースの全テーブルを切り捨てる
-
[解決済み] PostgreSQLのテーブルの行数を発見する高速な方法