web-dev-qa-db-ja.com

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

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

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

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

以下の回答で説明されているinformation_schemaビューを調べましたが、テーブルをかなりカバーしているようで、ビューもカバーしていると思われますが、まだ確認していません。

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

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

22
vfclists

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

私たちはこれについて何度も話し合いをしました。情報スキーマは特定の目的に役立ちます。システムカタログの使い方がわかっている場合は、ほとんどの目的に役立ちますbetter、IMO。システムカタログは、すべての情報の実際の情報源です。

情報スキーマは、さまざまなRDBMSプラットフォーム間での移植性は通常、クエリが洗練された後の幻想であるため、移植性に役立つ標準化されたビューを提供します。システムカタログを検索するのに十分です。そして、特に、 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に関する特別な知識はあまり必要ありません
  • 識別子は説明的で長く、扱いにくい場合があります

システムカタログ

  • 多くの場合、ソースに近い、より複雑な(依存する)
  • 速い
  • completeoidなどのシステム列が含まれます)
  • sQL標準に準拠していない
  • 主要なPostgresバージョン間で移植性が低下します(ただし、基本は変更されません)
  • postgresに関するより具体的な知識が必要
  • 識別子は簡潔で、説明は少なくなりますが、便利です。

任意のクエリ

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

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

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

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

_SELECT pg_typeof(1);
_
25

psqlコマンドラインクライアントを使用できます。

\dtはテーブルのリストを表示します

\dvはビューのリストを表示します

\d [object_name]は、テーブルまたはビューのスキーマを記述します

ただし、クエリをどのように記述するかわかりません。

詳細: https://manikandanmv.wordpress.com/tag/basic-psql-commands/

2
Neil McGuigan

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;

魅力のように機能し、非常に便利です。

2
marcopolo

the information_schema views を使用します。これらはSQL標準であり、必要な情報が含まれています。

pg_classpg_attributeなどに直接アクセスすることもできますが、これは移植性がなく、多くの場合面倒です。 oidvectortypespg_get_function_argumentsなどのヘルパー関数が必要になる場合があります。

psql\dtのようなものを実行する方法を確認したい場合は、psql -Eを実行します。クエリが出力されます。ただし、必要に応じてinformation_schemaを使用することをお勧めします。

1
Craig Ringer

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

enter image description here

1
David A