Permintaan untuk mengembalikan nama kolom output dan tipe data kueri, tabel, atau tampilan


21

Apakah ada kueri atau perintah PostgreSQL yang mengembalikan nama bidang dan jenis bidang kueri, tabel, atau tampilan?

Misalnya, solusi jika diterapkan pada permintaan SELECT sederhana seperti SELECT * from personharus mengembalikan daftar seperti:

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

Saya telah melihat information_schemapandangan yang dijelaskan dalam jawaban di bawah ini dan tampaknya mencakup tabel dengan cukup baik, dan saya menduga itu mencakup pandangan juga, tetapi saya belum memeriksanya.

Yang terakhir adalah setiap permintaan SELECT yang sewenang-wenang tetapi valid misalnya melibatkan JOINS,, UNIONSdll, pada basis data. Apakah ada prosedur bawaan, atau prosedur atau skrip tersimpan lainnya yang dapat mengembalikan yang sama untuk QUERY yang valid sama sekali?

Saya mengembangkan program yang membuat data dan formulir permintaan dan informasi diperlukan untuk fungsi validasi data dan mengeksekusi pada data yang dikembalikan.


Tidak ada "perintah" tunggal, jelas, tetapi ada berbagai cara untuk mengambil informasi dari katalog sistem. Tolong tanyakan pertanyaan spesifik , tambahkan contoh dan apa yang Anda harapkan sebagai imbalan, dan beri kami ide tentang niat di baliknya.
Erwin Brandstetter

1
Alasan untuk kesederhanaan adalah bahwa sejauh klien yang bersangkutan kueri yaitu SELECTkueri, yaitu non-pendefinisian data atau kueri manipulasi data, baik pada tabel, tampilan, atau kueri lain, mengembalikan baris dan kolom data, sehingga PostgreSQL harus dapat mengembalikan suatu daftar nama kolom dan tipe datanya. Tampilan yang information_schemadisebutkan di bawah dalam jawaban tampaknya menjawabnya untuk tabel dan tampilan. Pertanyaan SELECT sewenang-wenang adalah batas akhir. Saya akan mengedit jawaban untuk menjelaskan lebih baik
vfclists

Jawaban:


22

Skema informasi vs. katalog sistem

Kami telah berdiskusi tentang hal ini berkali-kali. Skema informasi melayani tujuan tertentu. Jika Anda tahu jalan di katalog sistem, yang melayani sebagian besar tujuan lebih baik , IMO. Katalog sistem adalah sumber aktual semua informasi.

The informasi skema menyediakan standar pandangan yang membantu dengan portabilitas, sebagian besar di versi Postgres besar, karena portabilitas di seluruh platform RDBMS yang berbeda biasanya adalah ilusi sekali pertanyaan Anda yang cukup canggih untuk kebutuhan untuk mencari katalog sistem. Dan, terutama, Oracle masih tidak mendukung skema informasi.

Tampilan dalam skema informasi harus melewati banyak rintangan untuk mencapai format yang memenuhi standar. Ini membuat mereka lambat, terkadang sangat lambat. Bandingkan paket dan kinerja untuk objek-objek dasar ini:

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

Perbedaannya luar biasa. Itu benar-benar tergantung pada apa yang Anda cari.

Contoh anda

Sebagai contoh Anda SELECT * from tbl, bandingkan dua kueri di bawah ini untuk tabel sederhana ini:

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

Menggunakan 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() mengembalikan tipe lengkap dengan semua pengubah:

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

Juga perhatikan bahwa para pemain untuk regclassmenyelesaikan nama tabel agak cerdas sesuai dengan saat ini search_path. Itu juga menimbulkan pengecualian jika nama tidak valid. Detail:

Menggunakan information_schema.columns:

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

Informasi terstandarisasi, tetapi tidak lengkap :

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

Untuk mendapatkan informasi lengkap untuk tipe data, Anda perlu mempertimbangkan semua kolom ini sebagai tambahan:

character_maximum_length
character_octet_length
numeric_precision
numeric_precision_radix
numeric_scale
datetime_precision
interval_type
interval_precision

Jawaban terkait:

Daftar pro & kontra , pro terbesar (IMO) dicetak tebal:

Tampilan skema informasi

  • seringkali lebih sederhana (tergantung)
  • lambat
  • preprocessed, yang mungkin sesuai atau tidak dengan kebutuhan Anda
  • selektif (pengguna hanya melihat objek yang memiliki hak istimewa untuk mereka)
  • sesuai dengan standar SQL (yang diimplementasikan oleh beberapa RDBMS utama)
  • sebagian besar portabel di seluruh versi Postgres utama
  • tidak memerlukan banyak pengetahuan khusus tentang Postgres
  • pengidentifikasi bersifat deskriptif, panjang dan terkadang canggung

Katalog sistem

  • seringkali lebih kompleks (tergantung), lebih dekat ke sumbernya
  • cepat
  • selesai (kolom sistem seperti oidtermasuk)
  • tidak memenuhi standar SQL
  • kurang portabel di seluruh versi Postgres utama (tetapi dasar-dasarnya tidak akan berubah)
  • membutuhkan pengetahuan yang lebih spesifik tentang Postgres
  • pengidentifikasi singkat, kurang deskriptif tetapi mudah pendek

Permintaan sewenang-wenang

Untuk mendapatkan daftar nama dan tipe kolom yang sama dari kueri, Anda bisa menggunakan trik sederhana: BUAT tabel sementara dari output kueri, lalu gunakan teknik yang sama seperti di atas.

Anda dapat menambahkan LIMIT 0, karena Anda tidak memerlukan data aktual:

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

Untuk mendapatkan tipe data dari masing-masing kolom, Anda juga dapat menggunakan fungsi pg_typeof():

SELECT pg_typeof(1);

Terima kasih banyak. Saya telah mencari cara untuk mendapatkan datatype kolom di pg_attribute untuk sementara dan baru saja menemukan posting ini. Hargai pos Anda.
Melinda

Ini membantu secara umum, tetapi tidak menjawab pertanyaan awal tentang bagaimana mendapatkan informasi tentang tipe data kolom yang diberikan oleh pernyataan SELECT. Itu bukan tentang kolom pandangan atau tabel, yang tentu saja berada di katalog sistem dan ditampilkan dalam skema informasi juga.
Holger Jakobs


2

Jika Anda memiliki akses ke pg_catalog dan menggunakan PgAdmin3, saya sangat merekomendasikan solusi yang saya temukan di blog Tech Valentine ( http://tech.valgog.com/2011/02/pgadmin-iii-macros-get-table-fields. html ). Ini adalah makro PgAdmin3 yang dapat diakses dengan pintasan untuk menampilkan definisi nama tabel yang dipilih.

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;

Bekerja seperti pesona dan sangat berguna.


1

Gunakan dengan information_schemapandangan , mereka SQL-standar dan mengandung informasi yang Anda inginkan.

Anda juga dapat langsung akses pg_class, pg_attribute, dll, tapi itu unportable dan sering fiddlier; Anda mungkin perlu fungsi pembantu sepertioidvectortypes , pg_get_function_arguments, dll untuk beberapa hal.

Jika Anda ingin melihat bagaimana psqlmengeksekusi sesuatu seperti \dt, jalankan psql -E- itu akan mencetak kueri. Namun, biasanya lebih baik menggunakan information_schemajika itu akan memenuhi kebutuhan Anda.


1

Ini mungkin terlalu sederhana, tetapi pgAdmin4 menunjukkan tipe bidang dalam hasil keluaran. Solusi lain di atas mungkin lebih elegan, tetapi ketika saya hanya perlu jawaban cepat, saya menemukan permintaan GUI pgAdmin4 bekerja dengan sangat baik. Mencoba mengetahui tipe bidang dari bidang terhitung yang dikembalikan oleh tampilan atau fungsi bisa rumit.

masukkan deskripsi gambar di sini


Sangat menyenangkan pgAdmin4 melakukan ini, tetapi bagaimana melakukannya? Bisakah kita mengetahuinya tanpa memindai melalui semua kode sumber PgAdmin4?
Holger Jakobs
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.