クエリ、テーブル、またはビューの出力列名とデータ型を返すクエリ


21

クエリ、テーブル、またはビューのフィールド名とフィールドタイプを返すPostgreSQLクエリまたはコマンドはありますか?

たとえば、次のような単純なSELECTクエリに適用されるソリューションは、次のようなSELECT * from personリストを返します。

Column Name   | Column Type
===========================
First Name    | character
Last Name     | character
Age           | integer
Date of Birth | date

私はinformation_schema以下の回答に記載されているビューを調べましたが、テーブルを非常によくカバーしているようで、ビューもカバーしていると思われますが、まだチェックしていません。

最後は、任意の、しかし有効なSELECTクエリです。たとえば、データベースに対するJOINSUNIONSなどが含まれます。組み込みプロシージャ、または有効なQUERYに対してまったく同じを返すことができる他のストアドプロシージャまたはスクリプトはありますか?

データを作成し、フォームにクエリを実行するプログラムを開発しています。この情報は、データの検証と返されたデータに対する関数の実行に必要です。


明らかに、単一の「コマンド」はありませんが、システムカタログから情報を取得するさまざまな方法があります。お問い合わせ下さい特定の質問を、例と何を見返りに期待を追加し、私たちにその背後にある意図についての考えを与えます。
アーウィンブランドステッター14

1
単純である理由は、クライアントに関する限り、クエリ、つまりSELECTクエリ、つまり非データ定義クエリまたはデータ操作クエリに関しては、テーブル、ビュー、または他のクエリでデータの行と列が返されるため、PostgreSQLは列名とそのデータ型のリスト。information_schema答えを下に言及したビューは、テーブルとビューのためにそれに答えるように表示されます。任意のSELECTクエリが最後のフロンティアです。私は答えを編集してより良い説明をします
vfclists 14

回答:


22

情報スキーマシステムカタログ

これについて何度も議論を重ねてきました。情報スキーマは特定の目的を果たします。システムカタログの使用方法を知っていれば、ほとんどの目的に適しています、IMO。システムカタログは、すべての情報の実際のソースです。

情報スキーマは、クエリは、システムカタログを検索する必要があるために、洗練された十分にあるいったん別のRDBMSプラットフォーム間での移植は通常、錯覚であるので、そのほとんどが主要なPostgresのバージョン間での移植のヘルプ、標準のビューを提供します。そして、特に、Oracleはまだ情報スキーマをサポートしていません。

情報スキーマ内のビューは、標準に準拠した形式を実現するために多くのフープをジャンプする必要があります。これにより、それらは遅くなり、時には非常に遅くなります。これらの基本オブジェクトの計画とパフォーマンスを比較します。

EXPLAIN ANALYZE SELECT * from information_schema.columns;
EXPLAIN ANALYZE SELECT * from pg_catalog.pg_attribute;

その違いは顕著です。それは本当にあなたが探しているものに依存します。

あなたの例

あなたの例ではSELECT * from tbl、この単純なテーブルについて以下の2つのクエリを比較します。

CREATE TEMP TABLE foo(
   A numeric(12,3)
 , b timestamp(0)
);

を使用してpg_attribute

SELECT attname, format_type(atttypid, atttypmod) AS type
FROM   pg_attribute
WHERE  attrelid = 'foo'::regclass
AND    attnum > 0
AND    NOT attisdropped
ORDER  BY attnum;

format_type() すべての修飾子を含む完全な型を返します。

attname | type
--------+-------------------------------
a       | numeric(12,3)
b       | timestamp(0) without time zone

また、キャストregclassは、現在のに従ってテーブル名をいくぶんインテリジェントに解決することに注意してくださいsearch_path。また、名前が無効な場合は例外が発生します。詳細:

を使用してinformation_schema.columns

SELECT column_name, data_type
FROM   information_schema.columns
WHERE  table_name = 'foo'
ORDER  BY ordinal_position;

情報は標準化されていますが、不完全です:

column_name | data_type
------------+----------------------------
a           | numeric
b           | timestamp without time zone

データ型の完全な情報を取得するには、これらすべての列をさらに考慮する必要があります。

character_maximum_length
character_octet_length
numeric_precision
numeric_precision_radix
numeric_scale
datetime_precision
interval_type
interval_precision

関連する回答:

長所と短所、太字の最大の長所(IMO)のリスト:

情報スキーマビュー

  • 多くの場合より単純です(依存します)
  • スロー
  • 前処理済み、ニーズに合っている場合とない場合がある
  • 選択的(ユーザーは特権を持っているオブジェクトのみを表示します)
  • SQL標準に準拠(主要なRDBMSのいくつかによって実装されています)
  • ほとんどの主要なPostgresバージョン間で移植可能
  • Postgresについての特別な知識は必要ありません
  • 識別子は説明的で長く、時には扱いにくい

システムカタログ

  • 多くの場合、ソースにより近い、より複雑な(依存する)
  • 速い
  • 完全oid含まれるようなシステム列)
  • SQL標準に準拠していない
  • 主要なPostgresバージョン間での移植性が低い(ただし、基本は変わらない)
  • Postgresについてより具体的な知識が必要
  • 識別子は簡潔で、説明的ではありませんが、便利な短いです

任意のクエリ

クエリから同じ列名と型のリストを取得するには、クエリ出力から一時テーブルを作成し、上記と同じテクニックを使用するという簡単なトリックを使用できます。

LIMIT 0実際のデータは必要ないため、を追加できます。

CREATE TEMP TABLE tmp123 AS
SELECT 1::numeric, now()
LIMIT  0;

個々の列のデータ型を取得するには、関数を使用することもできますpg_typeof()

SELECT pg_typeof(1);

どうもありがとうございます。私はしばらくの間pg_attributeの列のデータ型を取得する方法を探していましたが、この投稿に出くわしました。投稿に感謝します。
メリンダ

これは一般的には役立ちますが、SELECTステートメントが配信する列のデータ型に関する情報を取得する方法についての元の質問には答えません。もちろん、システムカタログに存在し、情報スキーマにも表示されるビューまたはテーブルの列に関するものではありません
ホルガージェイコブス


2

pg_catalogにアクセスしてPgAdmin3を使用している場合は、バレンタインのTechブログ(http://tech.valgog.com/2011/02/pgadmin-iii-macros-get-table-fields。)で見つけたソリューションを強くお勧めします。 html)。これは、選択したテーブル名の定義を表示するショートカットでアクセスできるPgAdmin3マクロです。

select quote_ident(nspname) || '.' || quote_ident(relname) as table_name, 
       quote_ident(attname) as field_name, 
       format_type(atttypid,atttypmod) as field_type, 
       case when attnotnull then ' NOT NULL' else '' end as null_constraint,
       case when atthasdef then 'DEFAULT ' || 
                                ( select pg_get_expr(adbin, attrelid) 
                                    from pg_attrdef 
                                   where adrelid = attrelid and adnum = attnum )::text else ''
       end as dafault_value,
       case when nullif(confrelid, 0) is not null
            then confrelid::regclass::text || '( ' || 
                 array_to_string( ARRAY( select quote_ident( fa.attname ) 
                                           from pg_attribute as fa 
                                          where fa.attnum = ANY ( confkey ) 
                                            and fa.attrelid = confrelid
                                          order by fa.attnum 
                                        ), ','
                                 ) || ' )'
            else '' end as references_to
  from pg_attribute 
       left outer join pg_constraint on conrelid = attrelid 
                                    and attnum = conkey[1] 
                                    and array_upper( conkey, 1 ) = 1,
       pg_class, 
       pg_namespace
 where pg_class.oid = attrelid
   and pg_namespace.oid = relnamespace
   and pg_class.oid = btrim( '$SELECTION$' )::regclass::oid
   and attnum > 0
   and not attisdropped
 order by attrelid, attnum;

チャームのように機能し、非常に便利です。


1

を使用するinformation_schemaビューをます。ビューはSQL標準であり、必要な情報が含まれています。

あなたはまた、直接アクセスすることができpg_classpg_attributeなどを、それは移植不可能だとしばしばfiddlier。次のようなヘルパー関数が必要になる場合がありますoidvectortypespg_get_function_argumentsいくつかのもののため、など。

あなたはどのように確認したい場合psqlなどの実行の何かが\dt、実行するpsql -E-それは、クエリを印刷します。ただし、通常information_schema、ニーズに合う場合はを使用することをお勧めします。


1

これは非常に単純かもしれませんが、pgAdmin4は出力結果にフィールドタイプを表示します。上記の他のソリューションはおそらくよりエレガントですが、簡単な答えが必要な場合、pgAdmin4のクエリGUIが非常にうまく機能することがわかります。ビューまたは関数によって返される計算フィールドのフィールドタイプを把握しようとすると、注意が必要です。

ここに画像の説明を入力してください


pgAdmin4がこれを行うことは非常に素晴らしいことですが、どのようにそれを行うのでしょうか?PgAdmin4のすべてのソースコードをスキャンせずに確認できますか?
ホルガーヤコブス
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.